<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="https://drl.chaosforge.org/w/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://drl.chaosforge.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Epyon</id>
		<title>DRL Wiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://drl.chaosforge.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Epyon"/>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Special:Contributions/Epyon"/>
		<updated>2026-04-29T16:05:40Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.21.1</generator>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Levels</id>
		<title>Levels</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Levels"/>
				<updated>2025-08-11T12:39:59Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
Levels are the heart of DRL, and without them there would be no game. It is where the player explores, where enemies roam, where special items lie in wait. They are filled with either fortune or your own personal demise.&lt;br /&gt;
&lt;br /&gt;
==Basic Objects==&lt;br /&gt;
All levels are made of basic objects like floors, walls, and doors.&lt;br /&gt;
*'''HP''': This is one of the parameters that governs how difficult the object is to destroy. Whenever an object takes damage, its HP is decreased. Once its HP falls to 0, it changes to a floor tile. Some objects cannot be destroyed; these are indicated as &amp;quot;none&amp;quot;. Also, some objects have two versions: one that can be destroyed and one that can't.&lt;br /&gt;
*'''Armor''': This also makes objects harder to destroy. Whenever an object takes damage, the object's armor is subtracted from the damage before the damage is subtracted from HP. Unlike the armor of the player and enemies, objects' armor can reduce damage to 0.&lt;br /&gt;
*'''Fragile''': Objects can usually only be damaged by [[Damage type#plasma|plasma]], [[Damage type#fire|fire]], or [[Damage type#acid|acid]] damage. Fragile objects can be damaged by any damage type.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;rules: cols; border: 2px solid darkred; border-spacing: 0; font-size: 90%; margin: 0.25em 0.5em;&amp;quot;&lt;br /&gt;
|colspan=11 style=&amp;quot;background: darkred; color: yellow; font-size: 120%; text-align: center&amp;quot;|'''Basic Objects'''&lt;br /&gt;
|- &lt;br /&gt;
|style=&amp;quot;text-align: center; padding: 1ex; border: solid darkred; border-width: 0 1px 1px 0&amp;quot; width=100|'''Name'''&lt;br /&gt;
|style=&amp;quot;text-align: center; padding: 1ex; border: solid darkred; border-width: 0 1px 1px 1px&amp;quot; width=50|'''Appearance'''&lt;br /&gt;
|style=&amp;quot;text-align: center; padding: 1ex; border: solid darkred; border-width: 0 1px 1px 1px&amp;quot; width=50|'''HP'''&lt;br /&gt;
|style=&amp;quot;text-align: center; padding: 1ex; border: solid darkred; border-width: 0 1px 1px 1px&amp;quot; width=50|'''Armor'''&lt;br /&gt;
|style=&amp;quot;text-align: center; padding: 1ex; border: solid darkred; border-width: 0 1px 1px 1px&amp;quot; width=50|'''Fragile'''&lt;br /&gt;
|style=&amp;quot;text-align: center; padding: 1ex; border: solid darkred; border-width: 0 0 1px 1px&amp;quot;|'''Special'''&lt;br /&gt;
|- style=&amp;quot;background: #333;&amp;quot;&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 1px 1px 0 0&amp;quot;|floor&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 1px 1px 0 1px&amp;quot;|&amp;lt;span style=&amp;quot;color:silver&amp;quot;&amp;gt;'''&amp;amp;middot;'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 1px 1px 0 1px&amp;quot;|none&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 1px 1px 0 1px&amp;quot;|N/A&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 1px 1px 0 1px&amp;quot;|N/A&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 1px 0 0 1px&amp;quot;|N/A&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 0 1px 0 0&amp;quot;|blood&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|&amp;lt;span style=&amp;quot;color:maroon&amp;quot;&amp;gt;'''&amp;amp;middot;'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|none&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|N/A&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|N/A&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 0 0 1px&amp;quot;|N/A&lt;br /&gt;
|- style=&amp;quot;background: #333;&amp;quot;&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 0 1px 0 0&amp;quot;|pool of blood&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|&amp;lt;span style=&amp;quot;color:maroon&amp;quot;&amp;gt;'''&amp;amp;bull;'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|none&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|N/A&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|N/A&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 0 0 1px&amp;quot;|N/A&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 0 1px 0 0&amp;quot;|Phobos rock&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|&amp;lt;span style=&amp;quot;color:maroon&amp;quot;&amp;gt;'''.'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|none&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|N/A&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|N/A&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 0 0 1px&amp;quot;|N/A&lt;br /&gt;
|- style=&amp;quot;background: #333;&amp;quot;&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 0 1px 0 0&amp;quot;|wall, blooded wall&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|&amp;lt;span style=&amp;quot;color:silver;&amp;quot;&amp;gt;'''#'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;color:maroon;&amp;quot;&amp;gt;'''#'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|10&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|10&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|no&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 0 0 1px&amp;quot;|N/A&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 0 1px 0 0&amp;quot;|bloodstone, blooded wall&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|&amp;lt;span style=&amp;quot;color:maroon;&amp;quot;&amp;gt;'''#'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;'''#'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|15&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|10&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|no&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 0 0 1px&amp;quot;|N/A&lt;br /&gt;
|- style=&amp;quot;background: #333;&amp;quot;&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 0 1px 0 0&amp;quot;|green wall&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;'''#'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|15&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|10&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|no&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 0 0 1px&amp;quot;|N/A&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 0 1px 0 0&amp;quot;|crate, blooded crate&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|&amp;lt;span style=&amp;quot;color:olive;&amp;quot;&amp;gt;'''#'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;color:navy;&amp;quot;&amp;gt;'''#'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;color:maroon;&amp;quot;&amp;gt;'''#'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|5&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|5&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|no&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 0 0 1px&amp;quot;|N/A&lt;br /&gt;
|- style=&amp;quot;background: #333;&amp;quot;&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 0 1px 0 0&amp;quot;|ammo crate, armor crate, blooded crate&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|&amp;lt;span style=&amp;quot;color:yellow;&amp;quot;&amp;gt;'''#'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;color:olive;&amp;quot;&amp;gt;'''#'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;color:maroon;&amp;quot;&amp;gt;'''#'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|5&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|5&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 0 0 1px&amp;quot;|When destroyed, sometimes leaves behind ammo, armor, boots or medpacks depending on the crate type and seed. Note that walls have HP, a wall's hp can be downgraded to 1HP and still be standing.&lt;br /&gt;
|- &lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 0 1px 0 0&amp;quot;|closed door&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|&amp;lt;span style=&amp;quot;color:olive;&amp;quot;&amp;gt;'''+'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|6&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|4&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 0 0 1px&amp;quot;|Can be opened.&lt;br /&gt;
|-style=&amp;quot;background: #333;&amp;quot;&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 0 1px 0 0&amp;quot;|locked door&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|&amp;lt;span style=&amp;quot;color:olive;&amp;quot;&amp;gt;'''+'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|6&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|6&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 0 0 1px&amp;quot;|N/A&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 0 1px 0 0&amp;quot;|open door&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|&amp;lt;span style=&amp;quot;color:olive;&amp;quot;&amp;gt;'''/'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|none&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|N/A&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|N/A&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 0 0 1px&amp;quot;|Can be closed.&lt;br /&gt;
|- style=&amp;quot;background: #333;&amp;quot;&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 0 1px 0 0&amp;quot;|[[lever]]&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|&amp;lt;span style=&amp;quot;color:white;&amp;quot;&amp;gt;'''&amp;amp;'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|10&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|0&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|no&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 0 0 1px&amp;quot;|see link in name for details&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 0 1px 0 0&amp;quot;|barrel of fuel&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|&amp;lt;span style=&amp;quot;color:olive;&amp;quot;&amp;gt;'''0'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|2&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|3&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 0 0 1px&amp;quot;|Can be pushed. When destroyed, creates a radius 4 [[explosions|explosion]] dealing 5d5 [[Damage type#fire|fire damage]].&lt;br /&gt;
|- style=&amp;quot;background: #333;&amp;quot;&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 0 1px 0 0&amp;quot;|barrel of acid&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;'''0'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|2&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|4&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 0 0 1px&amp;quot;|Can be pushed. When destroyed, creates a radius 3 [[explosions|explosion]] dealing 6d6 [[Damage type#acid|acid damage]], sometimes leaving behind acid tiles.&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 0 1px 0 0&amp;quot;|barrel of napalm&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;'''0'''&amp;lt;/span&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|2&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|5&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 1px 0 1px&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 0 0 0 1px&amp;quot;|Can be pushed. When destroyed, creates a radius 2 [[explosions|explosion]] dealing 7d7 [[Damage type#fire|fire damage]], sometimes (often) leaving behind lava tiles.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Random levels==&lt;br /&gt;
The archetypical level in DRL is a randomly-generated one. It is produced in such a way that no two games are particularly alike. There are many special considerations within the game engine, although many of these are technical and unimportant from a gameplay perspective.&lt;br /&gt;
&lt;br /&gt;
* [[Level type]]&lt;br /&gt;
* [[Level feeling]]&lt;br /&gt;
* [[Level event]]&lt;br /&gt;
* [[Monster Generation]]&lt;br /&gt;
* [[Item Generation]]&lt;br /&gt;
* [[Room Generation]]&lt;br /&gt;
* [[Fluids]]&lt;br /&gt;
&lt;br /&gt;
== Special levels ==&lt;br /&gt;
In stark contrast to random levels, special levels are constant and many of them appear every game. A few are static levels you must always go through on their designated floors (with the exception of certain challenges disabling them), while the rest are optional levels you may enter inbetween floors if you find the stairs to them (the entry to which are highlighted by red stairs). Each special level tends to have a gimmick to it, and completing them without the right equipment and plan can be very difficult, especially so on harder difficulties, but they offer great rewards that you will have a hard time procuring normally (or even be unable to obtain at all otherwise), as well as substantial EXP to level you up to a greater degree.&lt;br /&gt;
&lt;br /&gt;
For obvious reasons, all of these pages are considered spoilers if you wish to learn how to beat them yourself. Some are particularly spoiler-heavy, though, and are indicated as such here.&lt;br /&gt;
&lt;br /&gt;
* [[Phobos Base Entry]]&lt;br /&gt;
* [[Hell's Arena]]&lt;br /&gt;
* [[The Chained Court]]&lt;br /&gt;
* [[Military Base]]&lt;br /&gt;
* [[Phobos Lab]]&lt;br /&gt;
* [[Phobos Anomaly]]&lt;br /&gt;
* [[Hell's Armory]]&lt;br /&gt;
* [[Deimos Lab]]&lt;br /&gt;
* [[The Wall]]&lt;br /&gt;
* [[Containment Area]]&lt;br /&gt;
* [[Abyssal Plains]]&lt;br /&gt;
* [[City of Skulls]]&lt;br /&gt;
* [[Halls of Carnage]]&lt;br /&gt;
* [[Spider's Lair]]&lt;br /&gt;
* [[Tower of Babel]]&lt;br /&gt;
* [[The Vaults]]&lt;br /&gt;
* [[House of Pain]]&lt;br /&gt;
* [[Unholy Cathedral]] &amp;lt;font color=&amp;quot;#FFFF50&amp;quot;&amp;gt;(Spoilers!)&amp;lt;/font&amp;gt;&lt;br /&gt;
* [[The Mortuary]] &amp;lt;font color=&amp;quot;#FFFF50&amp;quot;&amp;gt;(Spoilers!)&amp;lt;/font&amp;gt;&lt;br /&gt;
* [[Limbo]] &amp;lt;font color=&amp;quot;#FFFF50&amp;quot;&amp;gt;(Spoilers!)&amp;lt;/font&amp;gt;&lt;br /&gt;
* [[The Lava Pits]]&lt;br /&gt;
* [[Mt. Erebus]]&lt;br /&gt;
* [[Dis]] &amp;lt;font color=&amp;quot;#FFFF50&amp;quot;&amp;gt;(Spoilers!)&amp;lt;/font&amp;gt;&lt;br /&gt;
* [[Hell Fortress]] &amp;lt;font color=&amp;quot;#FFFF50&amp;quot;&amp;gt;(MAJOR SPOILERS!)&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Special level placement===&lt;br /&gt;
Some levels don't spawn on I'm Too Young To Die: Hell's Armory/Deimos Lab, The Vaults/House of Pain, Unholy Cathedral, and The Mortuary/Limbo.&lt;br /&gt;
&lt;br /&gt;
Special stairs are always placed on a random empty tile.&lt;br /&gt;
&lt;br /&gt;
Special level pairs are chosen randomly - exactly one from each pair appears per game.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|'''Level'''&lt;br /&gt;
|'''Depth'''&lt;br /&gt;
|-&lt;br /&gt;
|Hell's Arena&lt;br /&gt;
|2 (Phobos 2)&lt;br /&gt;
|-&lt;br /&gt;
|The Chained Court&lt;br /&gt;
|5 (Phobos 5)&lt;br /&gt;
|-&lt;br /&gt;
|Phobos Lab/Military Base&lt;br /&gt;
|7 (Phobos 7)&lt;br /&gt;
|-&lt;br /&gt;
|Hell's Armory/Deimos Lab&lt;br /&gt;
|9 (Deimos 1)&lt;br /&gt;
|-&lt;br /&gt;
|The Wall/Containment Area&lt;br /&gt;
|11 (Deimos 3)&lt;br /&gt;
|-&lt;br /&gt;
|City of Skulls/Abyssal Plains&lt;br /&gt;
|12 (Deimos 4)&lt;br /&gt;
|-&lt;br /&gt;
|Spider's Lair/Halls of Carnage&lt;br /&gt;
|14 (Deimos 6)&lt;br /&gt;
|-&lt;br /&gt;
|The Vaults/House of Pain&lt;br /&gt;
|17 (Hell 1)&lt;br /&gt;
|-&lt;br /&gt;
|Unholy Cathedral&lt;br /&gt;
|19 (Hell 3)&lt;br /&gt;
|-&lt;br /&gt;
|The Mortuary/Limbo&lt;br /&gt;
|20 (Hell 4)&lt;br /&gt;
|-&lt;br /&gt;
|The Lava Pits/Mt. Erebus&lt;br /&gt;
|22 (Hell 6)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Strategy:Ultra-violence</id>
		<title>Strategy:Ultra-violence</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Strategy:Ultra-violence"/>
				<updated>2025-08-11T12:39:42Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
&lt;br /&gt;
== Welcome to Hell ==&lt;br /&gt;
The name does not lie. Ultra-Violence is ultra-hard. Enemies get a +2 bonus to their accuracy, making it almost certain that even weak enemies will hit you if you're not dodging, and [[hell knight]]s can start spawning on level ''3,'' which means you get one level after [[Phobos Base Entry]], maybe [[Hell's Arena]], before you have to fight them. [[Demon]]s will be appearing right from the start. Barons of Hell will appear on level 6. [[Revenant]]s and [[Former commando]]s can start spawning while you're still in ''Phobos,'' and of course [[Mancubi]] and [[Arch-vile]]s will become common enemies early in Deimos.&lt;br /&gt;
&lt;br /&gt;
Fooling-around builds have no place on Ultra-Violence unless you're really, '''''really''''' good. You have no time to arm up or get stronger, and it's possible to get an unlucky spawn location such that the only door leading out of your starting room will put you face-to-face with a hell knight and six demons, so you'll die and die very early on unless you have a plan and know exactly what you're doing. Never let yourself drop below 40% health, since you can get killed by a great many things in one attack at that health. Get good at corner shooting, giftdropping, and radar-shooting, because you're gonna need them. It's time to really start skipping special levels if you don't have a plan to beat it, because they will just kill you more often than not. [[Phobos Lab]] contains over a dozen [[nightmare demon]]s, which are very likely to kill you even if you're prepared because they'll get stuck in narrow halls you need to enter to progress, and they won't come out until they see you. Without two levels of [[Hellrunner]], even running is too slow to get away from them.&lt;br /&gt;
&lt;br /&gt;
On the bright side, though, there's now a guaranteed green armor in [[Phobos Base Entry]]! It'll almost certainly be used, but it's something!&lt;br /&gt;
&lt;br /&gt;
Since you have no time to prepare before the going gets ridiculously tough, you have to be familiar with the game's base mechanics and know what to do for every little situation that crops up. D veterans may be tempted to start here, but really, do not. You'll lose so fast that it won't teach you anything. You may also want to skip going for 100% kills every time until you're familiar with the difficulty level. It may level you up faster, but you'll also put yourself in more of the already-increased danger.&lt;br /&gt;
&lt;br /&gt;
== Starting ==&lt;br /&gt;
Even the first level of the game will be a huge challenge if you don't know how to handle it. With no plan, it can kill you, or at best make you use one of your starting med-packs while leaving you no way to rescue the others. There is a better way, though. (see [[Strategy:Phobos Base Entry]])&lt;br /&gt;
&lt;br /&gt;
Once you're in, there are a few ways of surviving the first few levels with little issue, even with 100% kills barring a challenge run.&lt;br /&gt;
&lt;br /&gt;
=== Fast DPS ===&lt;br /&gt;
This is a risky but oftentimes rewarding strategy. Essentially what this entails is going for your DPS-increasing traits first, before any investment in survivability. For Rapid builds, that's [[Eagle Eye]] and [[Son of a Bitch]]. For Pistols, that's [[Son of a Gun]]. For shotgunners, that's [[Reloader]] and [[Finesse]]. Don't just go for your favorite DPS method, though, you need to have a plan, so it's better if this investment leads to something that also helps you survive.&lt;br /&gt;
&lt;br /&gt;
* If you get [[Eagle Eye]], go for 2 levels of that and then get [[Intuition]] 2. Use Rapid weapons over pistols, even if you're going for a pistol build. Being able to see huge clusters of enemies before you open that door and aggro them all is going to save your life. Even good players can't reliably make plans without more information.&lt;br /&gt;
&lt;br /&gt;
* If you get [[Finesse]], get [[Juggler]] next. Pick up every single [[shotgun]] you see. Now instead of reloading, press 2 to switch to your pistol and 3 to switch back to a shotgun. It will pick a shotgun that's already loaded every time, and this gives shotguns excellent DPS early-game at the cost of inventory slots. If you tossed your pistol, fear not, you can just use the mouse wheel (if you have one) to select fists then switch back to a shotgun.&lt;br /&gt;
&lt;br /&gt;
* If you get [[Son of a Gun]], good luck, because while this can and does definitely work, you're playing on an extra layer of hard mode now, and you're more likely to die by getting unlucky. With at least two levels of SoG, if you hit a Former once, use an aimed shot to finish it off. If you get Dualgunner, aimed shots will take out formers in one attack semi-reliably. Get all 3 levels of Son of a Gun before anything else if you go this route. This is realistically your only option in Angel of Marksmanship.&lt;br /&gt;
&lt;br /&gt;
* If you get [[Brute]], get [[Berserker]]. Being able to go berserk can save your life even if you need to run because of the resistances and action speed it grants you.&lt;br /&gt;
&lt;br /&gt;
=== Fast Movespeed ===&lt;br /&gt;
This is by far the most safe and reliable strategy: get two levels of Hellrunner first and use a shotgun for DPS. Obviously, your damage will be lower out the gate, but Hellrunner gives you so much safety over the long run it's not even funny. By far the biggest hurdle to reaching the rest of the game is survival, and Hellrunner will allow you to outrun Demons without switching tactics to Running as long as you're wearing green armor or lighter, especially as a Scout, and if you do start Running, outrunning them will be trivial. In addition, two levels of Hellrunner gives you an extra 30% chance to dodge attacks while sidestepping. This works independently of enemy Accuracy, but only if you're sidestepping as you move - basically, don't run directly at an enemy's line of fire or directly away from it and you'll roll a chance to dodge. This does basically nothing against formers, who can't really be dodged unless you have [[Dodgemaster]], but against [[imp]]s, [[hell knight]]s, [[cacodemon]]s, and [[Barons of Hell]]? You will dodge against those enemies 80% of the time at ''minimum.'' Your dodge chance is then capped if you start Running.&lt;br /&gt;
&lt;br /&gt;
Combined together, those stats mean you can now play ring around the rosie using columns and clusters of boxes. Without Hellrunner, if you take a step around a corner of a box cluster while an enemy is at the other corner, you'll take a step and that enemy will take a step forward and still be able to see you. They may even get to attack afterward, and you will NOT get to dodge because the last thing you did from that enemy's PoV was stand perfectly still. With Hellrunner 2, however, you're basically always moving at Running speed. Eventually, you will be able to move and move and move, and then on one of those moves you'll be out of the enemy's vision, which can give you time to reload your weapon, and possibly even enough time to take a step toward that enemy, which gives you a successful dodge roll, which causes them to hit themselves with their own attack as it collides with the wall you were just behind. Risky, but hilarious! It's even more reliable if you're Running.&lt;br /&gt;
&lt;br /&gt;
Because of this trick, you can play Bugs Bunny with the barons of hell, hell knights, and cacodemons. You can even use this trick to make pinkies forget they ever saw you and go running off somewhere else!&lt;br /&gt;
&lt;br /&gt;
Because of how good Hellrunner 2 is, you don't even really need Dodgemaster unless your build calls for it specifically. Once you get Hellrunner 2, it's better to start up your DPS path right away rather than delay it another level. Otherwise, you won't have enough DPS to kill the enemies this ''doesn't'' work against.&lt;br /&gt;
&lt;br /&gt;
=== Fast Intuition ===&lt;br /&gt;
This is mainly an option for Scouts, but can also be used by other classes as a hybrid of Fast DPS by taking Eagle Eye 1/2 first, then taking Intuition 1/2 next. Scouts, however, are the creme de la creme of this option, since they can just go Intuition at level 1 and 2. Now that you always know if there's something around every corner, you never have to take any risks you can't afford to handle right now, and you can also avoid blindly shooting into the fog if there's a powerup over there. Being able to sense powerups and know which levers to avoid is such an immense benefit in the first few levels that it can save a run. For that reason, this is an incredible option that can work even through Nightmare! runs.&lt;br /&gt;
&lt;br /&gt;
Once you get Intuition 2, start up a DPS level or two before you dive straight into Hellrunner (if you're allowed).&lt;br /&gt;
&lt;br /&gt;
== Good Luck ==&lt;br /&gt;
&lt;br /&gt;
From there, it's up to you to know your build and how strong it gets and how fast for what to take next! UV is going to test your fundamentals like no other and some builds may sadly stop being viable here unless you theorycraft something amazing. In which case, share your findings! It's always exciting to have more ways to play the game.&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Strategy:Demon</id>
		<title>Strategy:Demon</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Strategy:Demon"/>
				<updated>2025-08-11T12:39:34Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{infostrat switch}}&lt;br /&gt;
== Main Guide (v0.9.9.4) ==&lt;br /&gt;
&lt;br /&gt;
=== Version Changes (v0.9.9.5) ===&lt;br /&gt;
Nothing significant to the enemy itself.&lt;br /&gt;
&lt;br /&gt;
=== General Tactics ===&lt;br /&gt;
Basic strategy posted by [[User:Elephant|Elephant]] 22:43, November 15 2011 (GMT).&lt;br /&gt;
&lt;br /&gt;
Demons are the most melee-oriented enemies of the game. Lacking ranged attacks or any special abilities, their strategy consists of running up to the player to beat him up. They can't use doors or items, and will run trough any fluid to reach the player, which can be used effectively against them. The demons have a speed of 130%, meaning that while they can only attack in melee, they will reach the player quickly, are hard to run away from, and will often hit twice for a player's action. They hit fairly hard and have some armor, but lack any resistances. They rarely miss.&lt;br /&gt;
*Since demons don't have a ranged attack, they are harmless if they don't get close to you.  Unfortunately, you sometimes just turn a corner and find a demon really close to you, and when they do attack you it will hurt.  The key is to listen for the monster sounds, and recognize when there are demons nearby so you don't get surprised. [[User:Matt_S|Matt_S]] 5:22, November 10 2011 (GMT)&lt;br /&gt;
*They are fairly fast, so if you decide to run from them, you had better have a destination in mind that is close by, because, unless you have levels in Hellrunner or something else that boosts your speed, they will catch up to you. [[User:Tormuse|Tormuse]] 13:48, November 15 2011 (GMT)&lt;br /&gt;
**Running, which grants a 30% boost, will actually keep demons at bay (without worrying about other modifiers). Remember this if you are ever swarmed in a demon cave. [[User:S.K.Ren|S.K.Ren]] 17:07, November 14 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the early levels, demons can be quite lethal, as the player lacks effective means to dispose of them before they get close (doubly so for melee runs), but later, when the player has more traits, weaponary and armor, they will not pose a threat but in the most unlucky scenarios.&lt;br /&gt;
&lt;br /&gt;
       |HITS NEEDED TO KILL PLAYER                     |&lt;br /&gt;
       |no armor   | 1 armor   | 2 armor   | 4 armor   |&lt;br /&gt;
       |min|avg|max|min|avg|max|min|avg|max|min|avg|max|&lt;br /&gt;
 50hp  | 6 | 8 | 9 | 8 | 9 |10 | 9 |10 |13 |13 |17 |25 |&lt;br /&gt;
 100hp |13 |15 |17 |15 |17 |20 |17 |20 |25 |25 |34 |50 |&lt;br /&gt;
 60hp  | 8 | 9 |10 | 9 |10 |12 |10 |12 |15 |15 |20 |30 |&lt;br /&gt;
 120hp |15 |18 |20 |18 |20 |24 |20 |24 |30 |30 |40 |60 |&lt;br /&gt;
 80hp  |10 |12 |14 |12 |14 |16 |14 |16 |20 |20 |27 |40 |&lt;br /&gt;
 160hp |20 |23 |27 |23 |27 |32 |27 |32 |40 |40 |54 |80 |&lt;br /&gt;
&lt;br /&gt;
*In general, you should follow this mindset against demons:&lt;br /&gt;
*:Stay at range. Its the best way to deal with them, period.&lt;br /&gt;
*:Don't neglect basic scouting techniquies like corner checking and listening. Nothing is more embarassing than walking into a trap.&lt;br /&gt;
*:Be mindful of your weapon when dealing with them. And be sure it's loaded at all times, as it should be. [[User:S.K.Ren|S.K.Ren]] 17:07, November 14 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Intelligence Analysis ===&lt;br /&gt;
The AI of the demons is probably the simplest in the game. Without any ranged offense, the demons will just run towards the player or melee him. Their unability to open doors and disregard for lava or acid puts them at disadvantage.&lt;br /&gt;
*Demons are probably the most dangerous when there are other enemies around to distract you, either enemies that do have ranged attacks or other demons that are approaching from different angles so that you can't hurt them all at once with shotgun blasts.  If there are enemies that have ranged attacks, you should consider getting behind any cover that is nearby to keep from being shot at while you take care of the demons; if you don't have any cover, you should consider retreating if the enemies are too strong to take out easily, but the best solution to this situation is to simply do all you can to avoid it.  If you are attacked by multiple demons approaching from different angles, you might want to consider running, either as an actual retreat or simply to get them all in your line of fire. [[User:Matt_S|Matt_S]] 5:22, November 10 2011 (GMT)&lt;br /&gt;
*They also have a slightly lower visual radius than you, so if you do find yourself in a situation where you're not capable of dealing with them, just keep them at the edge of your visual range, and they won't be able to see you, so they won't chase you. [[User:Tormuse|Tormuse]] 13:48, November 15 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
==== Doors ====&lt;br /&gt;
Fighting demons is best done behind an open door, so that the door can be closed if one gets dangerously close. Then you can either wait for a while for the demon to stop chasing you and hopefully wander awayfrom the door (hard to know if you don't have tracking map/intuition 2), or get some distance to the door and blast it open letting the demons in. Note that some other monster might open the door, letting the demons in. Since demons are fast, it's usually better to close the door before they are just next to it, in case they get 2 moves.&lt;br /&gt;
&lt;br /&gt;
        #&lt;br /&gt;
        #&lt;br /&gt;
        #&lt;br /&gt;
        #xx&lt;br /&gt;
        #xx    c&lt;br /&gt;
       @/xx  &lt;br /&gt;
        #xx&lt;br /&gt;
        #xx&lt;br /&gt;
        #&lt;br /&gt;
&lt;br /&gt;
When the demon reaches the &amp;quot;x&amp;quot;, close the door.&lt;br /&gt;
&lt;br /&gt;
==== Fluids ====&lt;br /&gt;
Demons, unlike other non-flying non-boss monsters, will chase you through any fluid. This means that acid/lava pools will become quite useful when fighting demons, especially for melee builds or groups of demons, or when you are REALLY short of ammo. Note that this also means that an acid puddle in a corridor will not stop them at their tracks.&lt;br /&gt;
*You can maximize the benefit of their fluid-walking by shooting them with the a to knock them back, forcing them to walk over the same squares of acid or lava over and over again. [[User:Tormuse|Tormuse]] 13:48, November 15 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
By careful positioning, you can usually maximize the amount of harm the fluids will cause. Three turns on lava or seven on acid will kill them.&lt;br /&gt;
&lt;br /&gt;
    ##############&lt;br /&gt;
          &lt;br /&gt;
         ==&lt;br /&gt;
        ====&lt;br /&gt;
       X ====&lt;br /&gt;
          ==       c&lt;br /&gt;
       @  =&lt;br /&gt;
    ##############&lt;br /&gt;
&lt;br /&gt;
If you move to position X, the demon will have to move through 4 tiles of acid/lava, instead of 1.&lt;br /&gt;
    &lt;br /&gt;
Melee characters will want to fight next to acid/lava, so that the demon will have to stay in the fluid, taking damage every turn.&lt;br /&gt;
&lt;br /&gt;
           c&lt;br /&gt;
    #######/#######&lt;br /&gt;
    ===============&lt;br /&gt;
    ########X######&lt;br /&gt;
    &lt;br /&gt;
The correct position to take is marked by X.&lt;br /&gt;
&lt;br /&gt;
==== Barrels ====&lt;br /&gt;
Luring demons near barrels is somewhat harder than luring B:s and h:s, due to their considerable speed and the fact that you can't giftdrop and have to use yourself as a lure. ut, if there's a demon next to a barrel, you are far enough (or have fireangel) and there is nothing important that might blow up, go on. (Note that the knockback might blow the demon closer to you if the barrel's behind them.)&lt;br /&gt;
    &lt;br /&gt;
They might be useful for clearing early vaults, by placing them next to the vault door, opening it, running a bit away and blowing it up with a shotgun when the demons follow. Note that this might destroy the items inside, so it's a bit of gamble.&lt;br /&gt;
    &lt;br /&gt;
=== Weapon Usage ===&lt;br /&gt;
    &lt;br /&gt;
==== Melee ====&lt;br /&gt;
Melee is arguably the worst way to dispatch demons, since you are very likely to get hurt in the process, especially when you lack the traits to do any serious damage. However, using the tricks mentioned earlier in this guide will make it easier to survive to the point you can reliably kill them in one or two hits.&lt;br /&gt;
*Demons have a hefty +3 to hit for melee. However, the running tactic impacts this by causing a -3 chance to-hit, so while it's not as effective as it would be versus other enemies, it can still cause a demon to miss, sparing you that hit and hopefully giving you time to kill it. Keep in mind that your melee damage is halved during this time. [[User:S.K.Ren|S.K.Ren]] 17:07, November 14 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
In the start of the game it's recommended that you use another weapon or, if that is not possible, avoid them completely until you get beefier and recive better equipment.(And if you're doing a N! fist-only 100% run, you probably already knew you were screwed.)&lt;br /&gt;
    &lt;br /&gt;
===== Fists =====&lt;br /&gt;
Fighting demons with only your fist is almost always a very bad idea. Without brute, you will only make 1 point worth of damage every hit. With the demon having 25 hp, it will take you a long time and a ton of medpacks if you wish to kill them. With Brute1 and 2 the damage will rise to 2-4 and 5-7, but you will still take a few hits. However, with Brute 5 you will two-shot them everytime.(Note that berserking makes one-hit kills possible with Brute 4 and 5.)&lt;br /&gt;
    &lt;br /&gt;
Berserking and doing the fluid tricks will help a lot, but the best option might just be running away.&lt;br /&gt;
&lt;br /&gt;
 FIST HITS NEEDED TO KILL&lt;br /&gt;
            &lt;br /&gt;
          min|avg|max    &lt;br /&gt;
 No Brute|25 |25 |25&lt;br /&gt;
 Brute 1 | 7 | 9 |13&lt;br /&gt;
 Brute 2 | 4 | 5 |5&lt;br /&gt;
 Brute 3 | 3 | 3 |4&lt;br /&gt;
 Brute 4 | 2 | 3 |3&lt;br /&gt;
 Brute 5 | 2 | 2 |2&lt;br /&gt;
&lt;br /&gt;
===== Combat Knife =====&lt;br /&gt;
Finding a knife will make slaying demons in melee a lot easier. it will deal 1-8 damage with the average of 4 even without any traits. Also, it can be thrown, unlike any other melee weapon. It's a good idea to throw one (or even two with Juggler and Finesse) at the demon before contact to soften it a little.&lt;br /&gt;
    &lt;br /&gt;
One-hit kills are possible from Brute2 with Malicious Blades or while berserking.&lt;br /&gt;
&lt;br /&gt;
 KNIFE HITS NEEDED TO KILL&lt;br /&gt;
    &lt;br /&gt;
          min|avg|max&lt;br /&gt;
 No Brute| 4 | 7 |25&lt;br /&gt;
 Brute 1 | 3 | 4 |7&lt;br /&gt;
 Brute 2 | 2 | 3 |4&lt;br /&gt;
 Brute 3 | 2 | 2 |3&lt;br /&gt;
 Brute 4 | 2 | 2 |2&lt;br /&gt;
 Brute 5 | 2 | 2 |2&lt;br /&gt;
&lt;br /&gt;
===== Other =====&lt;br /&gt;
The Chainsaw will, like in the original D, make short work of demons, being capable to one-hit with just one trait of Brute. Getting the chainsaw is the point for most melee builds when solitary demons stop being threathening, only beign dangerous in groups.&lt;br /&gt;
&lt;br /&gt;
Chainswords are exactly like chainsaws, except more accurate. Piercing blades ignore armor, dealing 2 points more damage to demons. Chainsaw assemblies and melee uniques will wipe the floor with puny pinkies.&lt;br /&gt;
&lt;br /&gt;
 CHAINSAW HITS NEEDED TO KILL&lt;br /&gt;
     &lt;br /&gt;
          min|avg|max&lt;br /&gt;
 No Brute| 2 | 3 |13&lt;br /&gt;
 Brute 1 | 1 | 2 |5&lt;br /&gt;
 Brute 2 | 1 | 2 |4&lt;br /&gt;
 Brute 3 | 1 | 2 |3&lt;br /&gt;
 Brute 4 | 1 | 2 |2&lt;br /&gt;
 Brute 5 | 1 | 1 |2&lt;br /&gt;
&lt;br /&gt;
==== Pistols ====&lt;br /&gt;
Whitout SoG it's practically impossible to kill the demon with a pistol before it reaches you, and you need SoG2 to do so reliably. Dualwielding will kill quickly, but don't dualreload if a demon has managed to get at bite distance. Also, with enough SoG and power mods, you will be able to cause knockback, making demons even easier to kill without getting hurt.&lt;br /&gt;
*Pistols work if you can fire them fast enough. An unmodded pistol without SoG will rarely be able to take out a demon in one clip. This makes dealing with packs dangerous. If you're forced to use a pistol early game, you're best bet is to shoot them from out of sight(Use Aimed Shots to improve your chance of hitting) and finish them off with a second clip as they approach. [[User:S.K.Ren|S.K.Ren]] 17:07, November 14 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
 PISTOL HITS NEEDED TO KILL&lt;br /&gt;
    &lt;br /&gt;
         min|avg|max    &lt;br /&gt;
 No SoG | 5 | 9 |25   &lt;br /&gt;
 SoG 1  | 4 | 7 |25       &lt;br /&gt;
 SoG 2  | 4 | 5 |13   &lt;br /&gt;
 SoG 3  | 3 | 5 |9&lt;br /&gt;
 SoG 4  | 3 | 4 |7&lt;br /&gt;
 SoG 5  | 3 | 4 |5     &lt;br /&gt;
&lt;br /&gt;
==== Shotguns ==== &lt;br /&gt;
Shotguns are quite useful against demons. While they have be reloaded/pumped after every shot, the knockback lessens the effect. They can also hit multiple enemies at the same time, always hit, and need no traits to be effective.(Except the double shotty)&lt;br /&gt;
*Despite their armor, shotguns are probably the best way to take out a demon early on. The knockback will keep the demon from getting too close, and you can probably take it down with three or four shots, often without the demon getting a chance to attack you.  For the best ammo efficiency without too much risk, you should fire when the demon is a couple of squares away from the edge of your view. [[User:Matt_S|Matt_S]] 5:22, November 10 2011 (GMT)&lt;br /&gt;
    &lt;br /&gt;
The double shotgun needs, due to it's reload time, either specific tactics or Shottyman to be effective. With Shottyman, you can just step away from the demons and fire again, but without it, it can still be used quite effectively by using doors.&lt;br /&gt;
&lt;br /&gt;
 DOUBLE SHOTGUN AND DOORS&lt;br /&gt;
    &lt;br /&gt;
        #                      #                      #&lt;br /&gt;
        #                      #                      #&lt;br /&gt;
       @/c                    @+  c                  @/c&lt;br /&gt;
        #                      #                      #&lt;br /&gt;
    &lt;br /&gt;
 1.Open the door and       2.Close the door and      3.Repeat as necessary.&lt;br /&gt;
 fire.                       reload.&lt;br /&gt;
&lt;br /&gt;
Note that shotguns deal sharpnel damage and thus the demon's armor will block 4 instead of 2 points of damage. Shotguns suffer damage reduction at range.&lt;br /&gt;
    &lt;br /&gt;
 SHOTGUN BLASTS NEEDED TO KILL (Note that the vaules are for point-blank shots)&lt;br /&gt;
 &lt;br /&gt;
            |shotgun    |combat s.  |double s.&lt;br /&gt;
            |min|avg|max|min|avg|max|min|avg|max  &lt;br /&gt;
 no traits  | 2 | 3 | 9 | 2 | 3 |13 | 1 | 2 |4&lt;br /&gt;
 SoB 1      | 2 | 3 | 7 | 2 | 3 | 9 | 1 | 2 |4&lt;br /&gt;
 SoB 2      | 2 | 2 | 5 | 2 | 3 | 7 | 1 | 1 |3&lt;br /&gt;
 SoB 4      | 2 | 2 | 4 | 2 | 2 | 5 | 1 | 1 |2&lt;br /&gt;
 MAD        | 2 | 2 | 4 | 2 | 2 | 5 | 1 | 1 |2&lt;br /&gt;
 MAD + SoB2 | 2 | 2 | 3 | 2 | 2 | 4 | 1 | 1 |2&lt;br /&gt;
&lt;br /&gt;
==== Rapid-fire ====&lt;br /&gt;
    &lt;br /&gt;
===== Chaingun =====   &lt;br /&gt;
Without traits, you will miss a lot at long ranges, and your bullets will do only 1 point of damage half of time. Thus, it's better to use the shotgun on demons until you get a few traits, like EE, SoB or TH.&lt;br /&gt;
*Chainguns are like pistols on crack. Less accurate but waaaay more bullets. You can usually clear groups of 1-3 with a chaingun without issue. Just be sure to reload whenever you can. [[User:S.K.Ren|S.K.Ren]] 17:07, November 14 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
DO NOT RELOAD WHILE A DEMON IS NEXT TO YOU! You will get your ass handed to you. Rather, have a spare chaingun and pull it out of your pack if you run out of bullets.&lt;br /&gt;
&lt;br /&gt;
 CHAINGUN BULLETS NEEDED TO KILL &lt;br /&gt;
 &lt;br /&gt;
            min|avg|max&lt;br /&gt;
 no traits | 7 |13 |25&lt;br /&gt;
 SoB1      | 5 | 9 |25&lt;br /&gt;
 SoB2      | 5 | 7 |25&lt;br /&gt;
 SoB3      | 4 | 5 |13&lt;br /&gt;
 SoB4      | 4 | 5 |9&lt;br /&gt;
 SoB5      | 3 | 4 |7&lt;br /&gt;
&lt;br /&gt;
Note that the numbers here are for individual bullets, not bursts. To calculate amount of bursts needed, divide the result by 4 + amount of TH traits, and always round up. For example, With SoB2 and TH1, the average amount of bursts needed is 7 : (4 + 1) = 1.4 = 2.&lt;br /&gt;
    &lt;br /&gt;
===== Plasma Rifle =====&lt;br /&gt;
Using the plasma rifle on demons is usually waste of power cells. Do it only if you have no other ammo left, or as a last resort if you are low on health and there's a group of demons closing in. The plasma rifle will kill demons very fast, even without any traits. It ignores half of armor.&lt;br /&gt;
*Plasma Rifles are just super Chainguns. When you start finding those, you should have more than enough fire power to deal with demons. [[User:S.K.Ren|S.K.Ren]] 17:07, November 14 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
 PLASMA RIFLE BULLETS NEEDED TO KILL&lt;br /&gt;
 &lt;br /&gt;
            min|avg|max&lt;br /&gt;
 no traits | 5 | 9 |25 &lt;br /&gt;
 SoB1      | 4 | 7 |25&lt;br /&gt;
 SoB2      | 4 | 5 |13&lt;br /&gt;
 SoB3      | 3 | 5 |9&lt;br /&gt;
 SoB4      | 3 | 4 |7&lt;br /&gt;
 SoB5      | 3 | 4 |5&lt;br /&gt;
&lt;br /&gt;
To calculate bursts, x being the result from the chart: x : 6 + TH, rounded up.&lt;br /&gt;
    &lt;br /&gt;
==== Explosive ====&lt;br /&gt;
    &lt;br /&gt;
===== Rocket Launcher =====&lt;br /&gt;
Using the rocket launcher against solitary demons is a waste of rockets and potentially dangerous, but against groups of demons it's pretty useful and potentially dangerous. The explosion might knock some of them closer to you, so have shotty prepared, just in case.&lt;br /&gt;
    &lt;br /&gt;
The rocket launcher deals in theory 4-34 points of damage to demons, but practically the number is lower.&lt;br /&gt;
    &lt;br /&gt;
===== BFG9000 =====&lt;br /&gt;
You're not going to waste 40 power cells on a demon, are you?&lt;br /&gt;
*This of course can depend on the situation: if you don't have a shotgun or melee weapon and are caught in the middle of a swarm, it might not be a bad idea. It is highly unlikely that you will be stuck in this case, however, given that the BFG9000 appears halfway through the game and caves are spawning cacodemons by then. [[User:Game Hunter|Game Hunter]] 17:47, 10 January 2012 (CET)&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/VBFG9000</id>
		<title>VBFG9000</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/VBFG9000"/>
				<updated>2025-08-11T12:39:24Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
{{ranged weapon|&lt;br /&gt;
weapon_name=VBFG9000 - [[Big_Gun_Types|Big Gun Family]]|&lt;br /&gt;
weapon_dmg=Original +2 sides per die, [[explosions|radius]] +2|&lt;br /&gt;
weapon_avgdmg=Varies|&lt;br /&gt;
weapon_dmgtype=[[Damage type#Plasma|Plasma]]|&lt;br /&gt;
weapon_accuracy=Original|&lt;br /&gt;
weapon_ftime=Original|&lt;br /&gt;
weapon_rtime=Original|&lt;br /&gt;
weapon_clip=Original*1.5 (consumes 1.5 times original per shot)|&lt;br /&gt;
weapon_ammo=[[Power cell]]|&lt;br /&gt;
weapon_afire=None|&lt;br /&gt;
weapon_areload=[[Alternate reload#Overcharge|Overcharge]]|&lt;br /&gt;
weapon_get=[[Assemblies|Assembly]]: Any [[BFG 9000]] + PPP|&lt;br /&gt;
weapon_quote=N/A|&lt;br /&gt;
weapon_looks=&amp;lt;font color=&amp;quot;cyan&amp;quot;&amp;gt;&amp;lt;b&amp;gt;}&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;|&lt;br /&gt;
weapon_description=Assembly (same as original)|&lt;br /&gt;
weapon_other=N/A|&lt;br /&gt;
weapon_source=Modelled on the good ol' BFG&amp;amp;nbsp;9000}}&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Super_shotgun</id>
		<title>Super shotgun</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Super_shotgun"/>
				<updated>2025-08-11T12:39:14Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
{{ranged weapon|&lt;br /&gt;
weapon_name=Super shotgun|&lt;br /&gt;
weapon_dmg=(8d4)x2/16-64, [[Shotguns|normal shotgun blast]]|&lt;br /&gt;
weapon_avgdmg=20 &amp;amp;times; 0.93 &amp;amp;times; 2 = 37.4|&lt;br /&gt;
weapon_dmgtype=[[Damage type#shrapnel|Shrapnel]]|&lt;br /&gt;
weapon_accuracy=+0|&lt;br /&gt;
weapon_ftime=1.0 second|&lt;br /&gt;
weapon_rtime=1.5 seconds|&lt;br /&gt;
weapon_clip=2|&lt;br /&gt;
weapon_ammo=[[Shotgun shell]]|&lt;br /&gt;
weapon_afire=None|&lt;br /&gt;
weapon_areload=None|&lt;br /&gt;
weapon_get=Random (10+)|&lt;br /&gt;
weapon_quote=''This little baby brings back memories!''|&lt;br /&gt;
weapon_looks=&amp;lt;font color=&amp;quot;magenta&amp;quot;&amp;gt;&amp;lt;b&amp;gt;}&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;|&lt;br /&gt;
weapon_description=''After the first hellish invasion, weapon engineers designed the super shotgun as the world's first firearm designed to kill demons. And boy does it.''|&lt;br /&gt;
weapon_other=[[Nano-shrapnel]] Super Shotgun + P is one of the few &amp;quot;Click to win&amp;quot; class ultra-powerful weapons, but it also doesn't destroy items.|&lt;br /&gt;
weapon_source=DII (whaddya expect, Mario?)}}&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Nuclear_BFG_9000</id>
		<title>Nuclear BFG 9000</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Nuclear_BFG_9000"/>
				<updated>2025-08-11T12:39:06Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
{{ranged weapon|&lt;br /&gt;
weapon_name=Nuclear BFG 9000 - [[Big_Gun_Types|Big Gun Family]]|&lt;br /&gt;
weapon_dmg=8d6/8-48, [[explosions|radius]] 8|&lt;br /&gt;
weapon_avgdmg=28|&lt;br /&gt;
weapon_accuracy=+5|&lt;br /&gt;
weapon_dmgtype=[[Damage type#plasma|Plasma]]|&lt;br /&gt;
weapon_ftime=1.5 seconds|&lt;br /&gt;
weapon_rtime=N/A|&lt;br /&gt;
weapon_clip=40 (consumes 40 per shot)|&lt;br /&gt;
weapon_ammo=None|&lt;br /&gt;
weapon_areload=[[Alternate reload#nuke|Nuclear overcharge]]|&lt;br /&gt;
weapon_afire=None|&lt;br /&gt;
weapon_get=Random (22+) or [[The Mortuary]]/[[Limbo]]|&lt;br /&gt;
weapon_quote=None|&lt;br /&gt;
weapon_looks=&amp;lt;b&amp;gt;&amp;lt;font color=&amp;quot;fuchsia&amp;quot;&amp;gt;}&amp;lt;/font&amp;gt;&amp;lt;/b&amp;gt;|&lt;br /&gt;
weapon_description=''A self-charging BFG9000! How much more lucky can you get?''|&lt;br /&gt;
weapon_other=Just more lucky as to have [[Biggest fucking gun|two B and three F]] in order to clear the level in one click for free. The nuclear BFG 9000 automatically recharges 1 ammo on each of the wielder's actions. It cannot be otherwise reloaded or unloaded.|&lt;br /&gt;
weapon_source=The original BFG&amp;amp;nbsp;9000 is, of course, from D. The nuclear version appears to be unique to DRL. Imbalanced BFG Family is a significant part of the D/Quake universe, even in canon.|&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/BFG_9000</id>
		<title>BFG 9000</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/BFG_9000"/>
				<updated>2025-08-11T12:38:59Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
{{ranged weapon|&lt;br /&gt;
weapon_name=BFG 9000 - [[Big_Gun_Types|Big Gun Family]]|&lt;br /&gt;
weapon_dmg=10d6/10-60, [[explosions|radius]] 8|&lt;br /&gt;
weapon_avgdmg=35|&lt;br /&gt;
weapon_dmgtype=[[Damage type#Plasma|Plasma]]|&lt;br /&gt;
weapon_accuracy=+5|&lt;br /&gt;
weapon_ftime=1.0 second|&lt;br /&gt;
weapon_rtime=2.0 seconds|&lt;br /&gt;
weapon_clip=100 (consumes 40 per shot)|&lt;br /&gt;
weapon_ammo=[[Power cell]]|&lt;br /&gt;
weapon_afire=None|&lt;br /&gt;
weapon_areload=[[Alternate reload#Overcharge|Overcharge]]|&lt;br /&gt;
weapon_get=Random (20+), [[Halls of Carnage]], [[Spider's Lair]]|&lt;br /&gt;
weapon_quote=''HELL, NOW YOU'LL GET LOOSE!''|&lt;br /&gt;
weapon_looks=&amp;lt;font color=&amp;quot;magenta&amp;quot;&amp;gt;&amp;lt;b&amp;gt;}&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;|&lt;br /&gt;
weapon_description=''The Big Fucking Gun. Hell wouldn't be so fun without it.''|&lt;br /&gt;
weapon_other=The BFG 9000 is automatically equipped the first time it is picked up. (Juggler applies.) It deals half the normal amount of explosive knockback and doesn't harm the wielder.|&lt;br /&gt;
weapon_source=D}}&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Plasma_rifle</id>
		<title>Plasma rifle</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Plasma_rifle"/>
				<updated>2025-08-11T12:38:53Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
{{ranged weapon|&lt;br /&gt;
weapon_name=Plasma rifle - [[Rapid-fire_Types|Rapid-fire Family]]|&lt;br /&gt;
weapon_dmg=(1d7)x6/6-42|&lt;br /&gt;
weapon_avgdmg=4 &amp;amp;times; 6=24|&lt;br /&gt;
weapon_dmgtype=[[Damage type#Plasma|Plasma]]|&lt;br /&gt;
weapon_accuracy=+2|&lt;br /&gt;
weapon_ftime=1.0 second|&lt;br /&gt;
weapon_rtime=2.0 seconds|&lt;br /&gt;
weapon_clip=40|&lt;br /&gt;
weapon_ammo=[[Power cell]]|&lt;br /&gt;
weapon_afire=[[Alternate fire#Chain fire|Chain fire]]|&lt;br /&gt;
weapon_areload=[[Alternate reload#Overcharge|Overcharge]]|&lt;br /&gt;
weapon_get=Random (12+), dropped by [[Former commando|former commandos]].|&lt;br /&gt;
weapon_quote=''Peace through superior firepower!''|&lt;br /&gt;
weapon_looks=&amp;lt;font color=&amp;quot;teal&amp;quot;&amp;gt;&amp;lt;b&amp;gt;}&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;|&lt;br /&gt;
weapon_description=''A plasma rifle shoots multiple rounds of plasma energy -- frying some demon butt!''|&lt;br /&gt;
weapon_other=N/A|&lt;br /&gt;
weapon_source=D}}&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Vision</id>
		<title>Vision</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Vision"/>
				<updated>2025-08-11T12:38:42Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Vision (or line-of-sight) is the process by which tiles around the player are revealed.&lt;br /&gt;
&lt;br /&gt;
The player also has a sight [[Distance|radius]]. By default, this sight radius is 8, but it can be increased to 10 with the [[Traits|Cateye]] trait. Additionally, some other effects can reveal a limited number of objects outside the player's sight radius.&lt;br /&gt;
&lt;br /&gt;
Certain tiles (like walls) block the player's vision. The effects of these obstructions are calculated by a modification of Isaac Kuo's [http://roguebasin.roguelikedevelopment.org/index.php?title=Isaac_s_fast_beamcasting_LOS fast beam casting algorithm]. The exact algorithm used by DRL is open-source as a part of [http://sourceforge.net/projects/fpcvalkyrie/ FPC Valkyrie].&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Chaingun</id>
		<title>Chaingun</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Chaingun"/>
				<updated>2025-08-11T12:38:33Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
{{ranged weapon|&lt;br /&gt;
weapon_name=Chaingun - [[Rapid-fire_Types|Rapid-fire Family]]|&lt;br /&gt;
weapon_dmg=(1d6)x4/4-20|&lt;br /&gt;
weapon_avgdmg=3.5*4=14|&lt;br /&gt;
weapon_dmgtype=[[Damage type#bullet|Bullet]]|&lt;br /&gt;
weapon_accuracy=+2|&lt;br /&gt;
weapon_ftime=1.0 second|&lt;br /&gt;
weapon_rtime=2.5 seconds|&lt;br /&gt;
weapon_clip=40|&lt;br /&gt;
weapon_ammo=[[10mm ammo]]|&lt;br /&gt;
weapon_afire=[[Alternate fire#Chain fire|Chain fire]]|&lt;br /&gt;
weapon_areload=None|&lt;br /&gt;
weapon_get=Random (6+), dropped by [[Former captain|former captains]], and part of the rewards in [[Hell's Arena]].|&lt;br /&gt;
weapon_quote=''Phobos ReLEADed, oh yeah!''|&lt;br /&gt;
weapon_looks=&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;}&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;|&lt;br /&gt;
weapon_description=''Chaingun directs heavy firepower onto your opponent making him do the chaingun cha-cha.''|&lt;br /&gt;
weapon_other=N/A|&lt;br /&gt;
weapon_source=There are [http://en.wikipedia.org/wiki/Chain_gun chain guns] in real life. However, in the original D game, the chaingun looked more like a [http://en.wikipedia.org/wiki/Gatling_gun gatling gun] (of which this game [[gatling gun|also has]]).}}&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Double_chainsaw</id>
		<title>Double chainsaw</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Double_chainsaw"/>
				<updated>2025-08-11T12:38:23Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
{{melee weapon|&lt;br /&gt;
weapon_name=Double chainsaw - [[Melee_Types|Melee Family]]|&lt;br /&gt;
weapon_dmg=4d12/4-48|&lt;br /&gt;
weapon_avgdmg=26|&lt;br /&gt;
weapon_dmgtype=[[Damage type#Melee|Melee]]|&lt;br /&gt;
weapon_accuracy=-1|&lt;br /&gt;
weapon_afire=None|&lt;br /&gt;
weapon_get=[[Assemblies|Assembly]]: {{exotic link|chainsaw}} + PPB|&lt;br /&gt;
weapon_quote=N/A|&lt;br /&gt;
weapon_looks=&amp;lt;font color=&amp;quot;cyan&amp;quot;&amp;gt;&amp;lt;b&amp;gt;\&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;|&lt;br /&gt;
weapon_description=Assembly (same as original)|&lt;br /&gt;
weapon_other=N/A|&lt;br /&gt;
weapon_source=D 64.}}&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Chainsaw</id>
		<title>Chainsaw</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Chainsaw"/>
				<updated>2025-08-11T12:38:15Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
{{melee weapon|&lt;br /&gt;
weapon_name=Chainsaw - [[Melee_Types|Melee Family]]|&lt;br /&gt;
weapon_dmg=4d6/4-24|&lt;br /&gt;
weapon_avgdmg=14|&lt;br /&gt;
weapon_dmgtype=[[Damage type#Melee|Melee]]|&lt;br /&gt;
weapon_accuracy=+0|&lt;br /&gt;
weapon_afire=N/A|&lt;br /&gt;
weapon_get=Random (12+), and in [[The Chained Court]].|&lt;br /&gt;
weapon_quote=''BLOOD! BLOOD FOR ARMOK, GOD OF BLOOD!''|&lt;br /&gt;
weapon_looks=&amp;lt;font color=&amp;quot;magenta&amp;quot;&amp;gt;&amp;lt;b&amp;gt;\&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;|&lt;br /&gt;
weapon_description=''Chainsaw -- cuts through flesh like a hot knife through butter.''|&lt;br /&gt;
weapon_other=You get a [[Berserk Pack]] effect when you pick this weapon up the first time.|&lt;br /&gt;
weapon_source=D, of course.}}&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Modding:being_API_(0.9.9.7)</id>
		<title>Modding:being API (0.9.9.7)</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Modding:being_API_(0.9.9.7)"/>
				<updated>2025-08-11T12:37:18Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''This page is currently under construction.''&lt;br /&gt;
&lt;br /&gt;
== API ==&lt;br /&gt;
&lt;br /&gt;
Please note that the type &amp;quot;integer&amp;quot; indicates an numeric value without a decimal part.  It does not indicate the range of acceptable values.&lt;br /&gt;
&lt;br /&gt;
An argument name in [square brackets] is an optional one.  The function description will indicate how the function operates if it is omitted.&lt;br /&gt;
&lt;br /&gt;
The [[Modding:Thing#API|Thing API]] can also be used with beings.&lt;br /&gt;
&lt;br /&gt;
=== Being API Function List ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;border: 2px solid darkred; border-spacing: 0; font-size: 90%; margin: 0.25em 0.5em;&amp;quot;&lt;br /&gt;
 ! colspan=&amp;quot;2&amp;quot; style=&amp;quot;background: darkred; color: yellow; font-size: 120%; text-align: center&amp;quot;|Being Interface&lt;br /&gt;
 {{Table2Col&lt;br /&gt;
  |es=background: #333;&lt;br /&gt;
  |c1=font-weight:bold; text-align:right; vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |c2=padding:0px 2px;&lt;br /&gt;
  |{{modarg|Being}}|{{moddef|list|new|dot||BeingID|id}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|kill|cln||boolean|[overkill]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|ressurect|cln||integer|range}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|apply_damage|cln||integer|amount|BodyTarget|target|DamageType|[type]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|get_name|cln||boolean|[known]|boolean|[capitalize]}}&lt;br /&gt;
  |{{modarg|table}}|{{moddef|list|inv_items|cln}}&lt;br /&gt;
  |{{modarg|Item}}|{{moddef|list|get_eq_item|cln||EquipSlot|slot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|set_eq_item|cln||EquipSlot|slot|Item|item}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|add_inv_item|cln||Item|item}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|play_sound|cln||SoundID|sound}}&lt;br /&gt;
  |{{modarg|integer}}|{{moddef|list|get_total_resistance|cln||ResistType|resist|BodyTarget|[target]}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|quick_swap|cln}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|pickup|cln}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|unload|cln||Item|item}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|drop|cln||Item|item}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|use|cln||Item|item}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|wear|cln||Item|item}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|attack|cln||Being|target}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|attack|cln||Coord|target}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|fire|cln||Coord|target|Item|weapon}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|alt_fire|cln||Coord|target|Item|weapon}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|reload|cln}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|alt_reload|cln}}&lt;br /&gt;
  |{{modarg|integer}}, {{modarg|Coord}}|{{moddef|list|direct_seek|cln||Coord|dest}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|relocate|cln||Coord|dest}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|path_find|cln||Coord|dest|integer|cutoff|integer|maximum}}&lt;br /&gt;
  |{{modarg|integer}}, {{modarg|Coord}} or {{modarg|boolean}}|{{moddef|list|path_next|cln}}&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|flock_target|cln||integer|range|integer|mind|integer|maxd}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|msg|cln||string|msg_player|string|msg_being}}&lt;br /&gt;
  |{{modarg|Item}}|{{moddef|list|select_slot_by_letter|cln||string|letter}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|phase|cln||CellID|[cell]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|spawn|cln||BeingID|monster}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|act|cln||Coord|coord}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|eye_contact|cln||Coord|other}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|eye_contact|cln||Thing|other}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|in_sight|cln||Coord|other}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|in_sight|cln||Thing|other}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|is_player|cln}}&lt;br /&gt;
  |{{modarg|integer}}|{{moddef|list|set_items|cln||SetID|set}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|nuke|cln||integer|[time]}}&lt;br /&gt;
  |{{modarg|Item}}, {{modarg|boolean}}|{{moddef|list|pick_mod_item|cln||string|modletter|integer|techbonus}}&lt;br /&gt;
  |}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Being API Function Descriptions ===&lt;br /&gt;
;{{moddef|desc|new|dot|Being|BeingID|id}}&lt;br /&gt;
Creates a new being object from the specified blueprint.&lt;br /&gt;
:''id'': The ID of the being to create.&lt;br /&gt;
:'''Returns''': A reference to the new being object.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|kill|cln||boolean|[overkill]}}&lt;br /&gt;
Kills the being.&lt;br /&gt;
:''overkill'': ''Optional.'' If ''True'', the being will be gibbed (extra blood, inventory will not drop, and a corpse will not be placed).  If ''False'' the being will be killed normally.  If omitted, the being will be killed normally.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|ressurect|cln||integer|range}}&lt;br /&gt;
Resurrects the nearest eligble corpse in sight of the calling being.  Handles all message output.&lt;br /&gt;
:''range'': The maximum distance (in terms of movement) that a corpse can be in order to be eligble for resurrection.&lt;br /&gt;
NOTE: The function name is a misspelling.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|apply_damage|cln||integer|amount|BodyTarget|target|DamageType|[type]}}&lt;br /&gt;
Deals damage to the being.&lt;br /&gt;
:''amount'': The amount of damage the attack does.  This is not necessarily the amount of HP the being will lose; the being's resistance and armor may apply against this value.&lt;br /&gt;
:''target'': One of TARGET_INTERNAL, TARGET_TORSO, or TARGET_FEET.  TARGET_INTERNAL only uses the target's internal armor and resistances (equipment, for the most part, will be ignored).  TARGET_TORSO uses the item in the armor slot to help reduce the damage, and TARGET_FEET uses the item in the boots slot to help reduce the damage.&lt;br /&gt;
:''DamageType'': ''Optional.'' One of the named constants starting with &amp;quot;DAMAGE_&amp;quot;.  Indicates the type of damage being dealt, which influences the properties and effects the damage has on the target.  If omitted, DAMAGE_BULLET will be used.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|get_name|cln||boolean|[known]|boolean|[capitalize]}}&lt;br /&gt;
Returns the name of the being, with the appropriate preposition.&lt;br /&gt;
:''known'': ''Optional.'' If ''true'', the being will not use an article (a, an, or the) when getting the name string.  If ''false'', an article (a, an, or the) will be appended to the front of the name.  If omitted, the default is to use an article.  BF_UNIQUENAME determines when &amp;quot;the&amp;quot; is used instead of &amp;quot;a&amp;quot; or &amp;quot;an&amp;quot;.&lt;br /&gt;
:''capitalize'': ''Optional.'' If ''true'', the name of the being will be capitalized.  If ''false'', it will not be adjusted.  If omitted, the default is to not adjust.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|inv_items|cln|table}}&lt;br /&gt;
Gets an iterator over the items in the being's inventory.&lt;br /&gt;
:'''Returns''': A table containing references to each item in the being's inventory.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|get_eq_item|cln|Item|EquipSlot|slot}}&lt;br /&gt;
Retrieves the item in the indicated equipment slot.  Equivalent to &amp;quot;being.eq.''slotname''&amp;quot;, where ''slotname'' is &amp;quot;weapon&amp;quot;, &amp;quot;armor&amp;quot;, &amp;quot;boots&amp;quot;, or &amp;quot;prepared&amp;quot;.&lt;br /&gt;
:''slot'': One of SLOT_WEAPON, SLOT_ARMOR, SLOT_BOOTS, or SLOT_PREPARED.&lt;br /&gt;
:'''Returns''': A reference to the item equipped in the indicated slot.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|set_eq_item|cln||EquipSlot|slot|Item|item}}&lt;br /&gt;
Equips an item to the being.  Equivalent to &amp;quot;being.eq.''slotname'' = ''item''&amp;quot;, where slotname is &amp;quot;weapon&amp;quot;, &amp;quot;armor&amp;quot;, &amp;quot;boots&amp;quot;, or &amp;quot;prepared&amp;quot;.&lt;br /&gt;
:''slot'': One of SLOT_WEAPON, SLOT_ARMOR, SLOT_BOOTS, or SLOT_PREPARED.&lt;br /&gt;
:''item'': The item to equip to the slot.  If there is a different item in the slot already, it will be destroyed.  If nil, the equipped item is destroyed.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|add_inv_item|cln||Item|item}}&lt;br /&gt;
Adds an item to the being's inventory.&lt;br /&gt;
:''item'': The item to add.&lt;br /&gt;
:'''Returns''': ''True'' if the item was added.  ''False'' if the being's inventory is full.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|play_sound|cln||SoundID|sound}}&lt;br /&gt;
Plays a sound at the being's location.&lt;br /&gt;
:''sound'': The sound to play.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|get_total_resistance|cln|integer|ResistType|resist|BodyTarget|[target]}}&lt;br /&gt;
Gets the total resistance for being, given the resistance type and target.&lt;br /&gt;
:''resist'': The resistance to get the value for.&lt;br /&gt;
:''target'': ''Optional.'' One of TARGET_INTERNAL, TARGET_TORSO, or TARGET_FEET.  TARGET_INTERNAL only uses the target's internal resistance (equipment, for the most part, will be ignored).  TARGET_TORSO uses the item in the armor slot to calculate resistance, and TARGET_FEET uses the item in the boots slot to calculate resistance.  If omitted, TARGET_TORSO is used.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|quick_swap|cln|boolean}}&lt;br /&gt;
Switches the weapon in the &amp;quot;weapon&amp;quot; slot with the one in the &amp;quot;prepared&amp;quot; slot.  Expends energy on success.&lt;br /&gt;
:'''Returns''': ''True'' if the swap worked. ''False'' if it failed.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|pickup|cln|boolean}}&lt;br /&gt;
Attempts to pickup the item at the being's current location.  Expends energy on success.&lt;br /&gt;
:'''Returns''': ''True'' if the pickup succeeded, ''False'' if it failed.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|unload|cln|boolean|Item|item}}&lt;br /&gt;
Attempts to unload the indicated item.  Expends energy on success.&lt;br /&gt;
:''item'': The item to try to unload.&lt;br /&gt;
:'''Returns''': ''True'' if the unloading succeeded, ''False'' if it failed.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|drop|cln|boolean|Item|item}}&lt;br /&gt;
Attempts to drop an item.  Expends energy on success.&lt;br /&gt;
:''item'': The item to try to drop.&lt;br /&gt;
:'''Returns''': ''True'' if the drop succeeded, ''False'' if it failed.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|use|cln|boolean|Item|item}}&lt;br /&gt;
Attempts to use an item.  Expends energy on success.&lt;br /&gt;
:''item'': The item to try to use.&lt;br /&gt;
:'''Returns''': ''True'' if the use succeeded.  ''False'' if it failed.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|wear|cln|boolean|Item|item}}&lt;br /&gt;
Attempts to equip an item.  Expends energy on success.&lt;br /&gt;
:''item'': The item to try to wear.&lt;br /&gt;
:'''Returns''': ''True'' if the item was worn.  ''False'' if the command failed.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|attack|cln|boolean|Being|target}}&lt;br /&gt;
;{{moddef|desc|attack|cln|boolean|Coord|target}}&lt;br /&gt;
Attempts to attack something.  Expends energy on success.&lt;br /&gt;
:''target'': A being or a location to attack.&lt;br /&gt;
:'''Returns''': ''True'' if the attack was attempted.  ''False'' if the being couldn't attack.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|fire|cln|boolean|Coord|target|Item|weapon}}&lt;br /&gt;
Attempts to fire a weapon at something.  Expends energy on success.&lt;br /&gt;
:''target'': The location to fire at.&lt;br /&gt;
:''weapon'': The item to fire at the location with.&lt;br /&gt;
:'''Returns''': ''True'' if the weapon was fired.  ''False'' if it failed.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|alt_fire|cln|boolean|Coord|target|Item|weapon}}&lt;br /&gt;
Attempts to fire a weapon using its alternate fire mode.&lt;br /&gt;
:''target'': The location to fire at.&lt;br /&gt;
:''weapon'': The item to fire at the location with.&lt;br /&gt;
:'''Returns''': ''True'' if the weapon was fired.  ''False'' if it failed.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|reload|cln|boolean}}&lt;br /&gt;
Attempts to reload the equipped weapon.&lt;br /&gt;
:'''Returns''': ''True'' if the weapon was loaded with at least 1 ammo.  ''False'' if the weapon didn't get any ammo put in it at all.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|alt_reload|cln|boolean}}&lt;br /&gt;
Attemptes to reload the equipped weapon using its alternate reload.&lt;br /&gt;
:'''Returns''': ''True'' if the weapon was loaded with at least 1 ammo.  ''False'' if the weapon didn't get any ammo put in it at all.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|direct_seek|cln|integer, Coord|Coord|dest}}&lt;br /&gt;
Attempts to move directly toward a location.  Expends energy only on a successful move. The being will try moving around objects in its way.  It will only move at most 1 space for each time this is called.&lt;br /&gt;
:''dest'': The location to attempt to move toward.&lt;br /&gt;
:'''Returns''': An integer, representing the result of the move, and a Coord, holding the previous location of the being.  The integer can be 0 (MOVEOK), 1 (MOVEBLOCK), 2 (MOVEDOOR), or 3 (MOVEBEING).  0 means the move was successful, and energy was expended.  1 means there was a wall in the way.  2 means there was door or other CF_OPENABLE cell in the way.  3 means a being was in the way.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|relocate|cln||Coord|dest}}&lt;br /&gt;
Moves the being to the indicated location, with animations.&lt;br /&gt;
:''dest'': The location to move the being to.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|path_find|cln|boolean|Coord|dest|integer|cutoff|integer|maximum}}&lt;br /&gt;
Search for a path to the indicated location.  Pathfinding is a time intensive procedure, use conservatively.&lt;br /&gt;
:''dest'': The location to find a path to.&lt;br /&gt;
:''cutoff'': A path finding parameter.  The search is aborted if this number of positions are checked without getting closer to the target destination.  DRL uses 10 for normal enemies and 40 for bosses.  Larger values may cause the algorithm to take longer.&lt;br /&gt;
:''maximum'': A path finding parameter.  The search is aborted if this number of positions are checked without reaching the target.  DRL uses 40 for normal enemies and 200 for bosses.  Larger values may cause the algorithm to take longer.&lt;br /&gt;
:'''Returns''': ''True'' if a path was found, ''False'' if not.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|path_next|cln|integer, Coord}} or '''boolean'''&lt;br /&gt;
Moves the being to the next space on the found path.&lt;br /&gt;
:'''Returns''': If there is a valid path, an integer, representing the result of the move, and a Coord, holding the previous location of the being, are returned.  The integer can be 0 (MOVEOK), 1 (MOVEBLOCK), 2 (MOVEDOOR), or 3 (MOVEBEING).  0 means the move was successful, and energy was expended.  1 means there was a wall in the way.  2 means there was door or other CF_OPENABLE cell in the way.  3 means a being was in the way.  If there was no valid path to move along, the boolean value ''False'' is returned instead.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|flock_target|cln|Coord|integer|range|integer|mind|integer|maxd}}&lt;br /&gt;
Assigns a coord based on other beings of the same type.&lt;br /&gt;
:''range'': The distance to check.&lt;br /&gt;
:''mind'': Matching beings will try to keep this much distance between them.&lt;br /&gt;
:''maxd'': Matching beings will try to be at least this close to each other.&lt;br /&gt;
:'''Returns''': A coordinate.  If the beings are ''mind'' away or closer, the coordinate will be away from the closest matching being.  If the beings are ''maxd'' away or farther, the coordinate will be the location of the closest being.  Otherwise, the coordinate is a random position within ''range''.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|msg|cln||string|msg_player|string|msg_being}}&lt;br /&gt;
Prints a message depending on the status of the subject of the message.&lt;br /&gt;
:''msg_player'': ''Optional.'' If the calling being is the player, this message will be printed.  If omitted, no message is printed if called by the player.&lt;br /&gt;
:''msg_being'': ''Optional.'' If the calling being is not the player, but is in the player's vision, this message will be printed.  If omitted, no message is printed if called by a visible non-player being.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|select_slot_by_letter|cln|Item|string|letter}}&lt;br /&gt;
Gets the slot based on the character entered.&lt;br /&gt;
:''letter'': A single character string.&lt;br /&gt;
:'''Returns''': If letter is &amp;quot;a&amp;quot;, the item in the armor slot is returned.  If letter is &amp;quot;b&amp;quot;, the item in the boots slot is returned.  If letter is &amp;quot;w&amp;quot;, the item in the weapon slot is returned.  If letter is &amp;quot;p&amp;quot;, the item in the prepared slot is returned.  Otherwise, nil is returned.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|phase|cln||CellID|[cell]}}&lt;br /&gt;
Teleports the being to a new cell.&lt;br /&gt;
:''cell'': ''Optional.'' A cell id to search for.  If multiple cells of that id are on the level, one is picked at random.  If omitted, any cell empty of beings, items, stairs, walls, hazardous terrain, or LFNOSPAWN can be selected.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|spawn|cln||BeingID|monster}}&lt;br /&gt;
Summons monsters around this being.  Monsters summoned this way grant no experience to the player (that is, BF_NOEXP is set on the spawned beings).&lt;br /&gt;
:''monster'': The ID of the being to spawn.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|act|cln|boolean|Coord|coord}}&lt;br /&gt;
Makes the being interact with the indicated location.&lt;br /&gt;
:''coord'': The location to interact with.&lt;br /&gt;
:'''Returns''': ''True'' if the action was successful, ''False'' if not.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|eye_contact|cln|boolean|Coord|other}}&lt;br /&gt;
;{{moddef|desc|eye_contact|cln|boolean|Thing|other}}&lt;br /&gt;
Checks if something is visible from this being's location.&lt;br /&gt;
:''other'': A Coord, Being, or Item whose position will be checked.&lt;br /&gt;
:'''Returns''': ''True'' if the being can see the checked object or location, ''False'' if not.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|in_sight|cln|boolean|Coord|other}}&lt;br /&gt;
;{{moddef|desc|in_sight|cln|boolean|Thing|other}}&lt;br /&gt;
Checks to see if something can be from the being's location.  If the being is the player, the player's vision algorithm is used.  Otherwise, the being's eye_contact algorithm is used.&lt;br /&gt;
:''other'': A Coord, Being, or Item whose position will be checked.&lt;br /&gt;
:'''Returns''': ''True'' if the object is visible, ''False'' if not.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|is_player|cln|boolean}}&lt;br /&gt;
Returns whether this being is the player or not.&lt;br /&gt;
:'''Returns''': ''True'' if this being is the player.  ''False'' if it is not.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|set_items|cln|integer|SetID|set}}&lt;br /&gt;
Gets the number of items worn by the being that are part of a set.&lt;br /&gt;
:''set'': The set to check.&lt;br /&gt;
:'''Returns''': The number of items of that set worn by this being.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|nuke|cln||integer|[time]}}&lt;br /&gt;
Creates a nuke under the being and sets the nuke timer.&lt;br /&gt;
:''time'': ''Optional.'' The number of game turns the the nuke will go off in.  If omitted, the default is 1.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|pick_mod_item|cln|Item, boolean|string|modletter|integer|techbonus}}&lt;br /&gt;
Performs the choice, check, and attachment of a mod to an item.  Only the player can call this function.&lt;br /&gt;
:''modletter'': The letter representing the mod being attached. Standard DRL mod letters are:&lt;br /&gt;
  Agility: A     Tech:      T      Bulk: B     Power: P&lt;br /&gt;
  Sniper:  S     Firestorm: F      Nano: N     Onyx:  O&lt;br /&gt;
Custom modpacks should use different letters.&lt;br /&gt;
:''techbonus'': The number of points of tech bonus the being has.  DRL uses the Whizkid level for this number.&lt;br /&gt;
:'''Returns''': An Item and a boolean.  The Item returned is the resulting item after being modded with the mod pack, unless an assembly (mod array) was matched and accepted.  The boolean value is ''True'' if the modding was successful or ''False'' if it was not.  If the boolean value is ''False'' or the Item was turned into an assembly, Nil is returned instead of the item.&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Modding:Documentation</id>
		<title>Modding:Documentation</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Modding:Documentation"/>
				<updated>2025-08-11T12:37:04Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Players are allowed to load custom game content into the DRL engine using the Custom Game menu option. These packages (called modules, mods, or wads) of new content are created by various members of the DRL community; look for modules on the [http://forum.chaosforge.org/index.php/board,22.0.html modding forum].&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
As of right now the best place to learn about modding DRL is to view the source code of current mods and, if you can't find what you need there, to ask for advice on the Chaosforge IRC channel, #chaosforge. Mods and their sources can be found in the modding section of the Chaosforge forums. IRC, if you are not familiar with it already, can be accessed quickly by using a free web based IRC client like the one found [http://en.irc2go.com/webchat/?net=QuakeNet&amp;amp;room=Chaosforge here]. Unfortunately BOTH sources are filled with obsolete information, as is this wiki. It will get better over time.&lt;br /&gt;
&lt;br /&gt;
Although currently very out of date there is a [[Modding:Tutorial|series of tutorials]] in place to help with some of the basics of modding (as well as some advanced tricks for more experienced modders). It is suggested that you read through these if you want to understand most of the documentation. If you want to learn only enough to build a quick map, head to the tutorial [[Modding:Tutorial/Constructing a Map|Constructing a Map]] for guidelines and an example.&lt;br /&gt;
&lt;br /&gt;
If you're just here to figure out how to play modules, it is a very simple process:&lt;br /&gt;
&lt;br /&gt;
*Download either a folder with the .module extension (this is a &amp;quot;raw&amp;quot; module) or a file with the .WAD extension.&lt;br /&gt;
*Place the folder or file into your &amp;quot;modules&amp;quot; directory, located in your DRL folder.&lt;br /&gt;
*Start DRL, then select the &amp;quot;Custom Game&amp;quot; option.&lt;br /&gt;
*Select from any of the modules in the menu, at which point the normal game startup procedure will begin.&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
This section is documents the DRL modding system including the various objects and libraries available to modders.&lt;br /&gt;
&lt;br /&gt;
==== Modules ====&lt;br /&gt;
&lt;br /&gt;
* [[Modding:Module|Module]]&lt;br /&gt;
&lt;br /&gt;
==== Base Object ====&lt;br /&gt;
&lt;br /&gt;
* [[Modding:Thing|Thing]]&lt;br /&gt;
&lt;br /&gt;
==== Main Objects ====&lt;br /&gt;
&lt;br /&gt;
* [[Modding:Item|Items]]&lt;br /&gt;
* [[Modding:Missile|Missiles]]&lt;br /&gt;
* [[Modding:Cell|Cells]]&lt;br /&gt;
* [[Modding:being|Beings]] ([[Modding:being blueprint|b]] [[Modding:being API|a]] [[Modding:being object|o]])&lt;br /&gt;
* [[Modding:player|Player]] ([[Modding:player API|a]] [[Modding:player object|o]])&lt;br /&gt;
* [[Modding:level|Levels]] ([[Modding:level blueprint|b]] [[Modding:level API|a]] [[Modding:level object|o]])&lt;br /&gt;
&lt;br /&gt;
==== Secondary Objects ====&lt;br /&gt;
&lt;br /&gt;
* [[Modding:ItemSet|Item Sets]]&lt;br /&gt;
* [[Modding:ModArray|Assemblies]]&lt;br /&gt;
* [[Modding:Affects|Affects]]&lt;br /&gt;
* [[Modding:Generator|Generator]]&lt;br /&gt;
* [[Modding:Coord|Coordinates]]&lt;br /&gt;
* [[Modding:Area|Areas]]&lt;br /&gt;
* [[Modding:AI|AI]]&lt;br /&gt;
* [[Modding:UI|User Interface]]&lt;br /&gt;
* [[Modding:Command|Commands]]&lt;br /&gt;
&lt;br /&gt;
==== Other ====&lt;br /&gt;
&lt;br /&gt;
* [[Modding:Core|Core]]&lt;br /&gt;
* [[Modding:Functions|Functions]]&lt;br /&gt;
* [[Modding:Kills|Kills]]&lt;br /&gt;
* [[Modding:Statistics|Statistics]]&lt;br /&gt;
* [[Modding:Badge|Badges]]&lt;br /&gt;
* [[Modding:Medal|Medals]]&lt;br /&gt;
* [[Modding:Traits|Traits]]&lt;br /&gt;
* [[Modding:Challenges|Challenges]]&lt;br /&gt;
* [[Modding:RankExp|Experience Ranks]]&lt;br /&gt;
* [[Modding:RankSkill|Skill Ranks]]&lt;br /&gt;
&lt;br /&gt;
==== Constants ====&lt;br /&gt;
&lt;br /&gt;
* [[Modding:Constants|Constants]]&lt;br /&gt;
* [[Modding:Constants#Flags|Flags]]&lt;br /&gt;
* [[Modding:sID|Object IDs]]&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/High_power_pistol</id>
		<title>High power pistol</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/High_power_pistol"/>
				<updated>2025-08-11T12:36:46Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
{{ranged weapon|&lt;br /&gt;
weapon_name=High power pistol -  [[Pistol_Types|Pistol Family]]|&lt;br /&gt;
weapon_dmg= 2d6 / 2-12|&lt;br /&gt;
weapon_avgdmg= 7 |&lt;br /&gt;
weapon_dmgtype=Bullet|&lt;br /&gt;
weapon_accuracy=+4|&lt;br /&gt;
weapon_ftime=1.0 second|&lt;br /&gt;
weapon_rtime=1.2 seconds|&lt;br /&gt;
weapon_clip=4|&lt;br /&gt;
weapon_ammo=10mm ammo|&lt;br /&gt;
weapon_afire=Aimed shot|&lt;br /&gt;
weapon_areload=Dual reload|&lt;br /&gt;
weapon_get=[[Assemblies|Assembly]]: Pistol + PB|&lt;br /&gt;
weapon_quote=N/A|&lt;br /&gt;
weapon_looks=&amp;lt;font color=&amp;quot;cyan&amp;quot;&amp;gt;&amp;lt;b&amp;gt;}&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;|&lt;br /&gt;
weapon_description=Assembly (same as original)|&lt;br /&gt;
weapon_other=N/A|&lt;br /&gt;
weapon_source= [http://en.wikipedia.org/wiki/Browning_Hi-Power Real life] (Interestingly enough, in real life, high power was referring to the larger magazine round capacity of 13 shots, as opposed to higher damage as in DRL!)|}}&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Modding:Medal</id>
		<title>Modding:Medal</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Modding:Medal"/>
				<updated>2025-08-11T12:36:16Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Medals are [[achievements]] that are received, at most, once per game. As game objects, they are as functional as you require them to be.&lt;br /&gt;
&lt;br /&gt;
== Prototype ==&lt;br /&gt;
As with all DRL lua objects, medals can be defined in any way at all. The following keys are used in DRL's base wad file:&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;border: 2px solid darkred; border-spacing: 0; font-size: 90%; margin: 0.25em 0.5em;&amp;quot;&lt;br /&gt;
 ! colspan=&amp;quot;3&amp;quot; style=&amp;quot;background: darkred; color: yellow; font-size: 120%; text-align: center&amp;quot;|'''Medal Prototype'''&lt;br /&gt;
 {{Table3Col&lt;br /&gt;
  |es=background: #333;&lt;br /&gt;
  |c1=font-weight:bold; text-align:right; vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |c2=vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |c3=padding:0px 2px;&lt;br /&gt;
  |'''string'''|&amp;lt;u&amp;gt;id&amp;lt;/u&amp;gt;|This is the medal's sid. It must be distinct from other string ids.&lt;br /&gt;
  |'''string'''|&amp;lt;u&amp;gt;name&amp;lt;/u&amp;gt;|This is the medal as it appears on the mortem and player info screens.&lt;br /&gt;
  |'''string'''|&amp;lt;u&amp;gt;desc&amp;lt;/u&amp;gt;|This is a description of the medal as it appears on the player info screen.&lt;br /&gt;
  |'''boolean'''|hidden|This determines whether or not the medal is visible on the player info screen before the player has been given the medal.&lt;br /&gt;
  |'''function'''|condition|This is a function that is used to set up the requirements for the medal. It usually looks at [[Modding:Statistics|statistics]] accrued throughout the game.&lt;br /&gt;
  |'''boolean'''|winnoly|This determines if the medal is only received if the player wins the game. This is only necessary if the medal has been assigned a condition key.&lt;br /&gt;
  |'''list'''|removes|This is a list of medal ids. Any medals added to this list will not be gained if this medal has been given. This is only necessary if the medal has been assigned a condition key.&lt;br /&gt;
  |}}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Strategy:Shottyman</id>
		<title>Strategy:Shottyman</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Strategy:Shottyman"/>
				<updated>2025-08-11T12:36:10Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{infostrat switch}}&lt;br /&gt;
== Main Guide (v0.9.9.4) ==&lt;br /&gt;
&lt;br /&gt;
=== Version Changes (v0.9.9.5) ===&lt;br /&gt;
Nothing significant to the trait itself.&lt;br /&gt;
&lt;br /&gt;
=== General Tactics ===&lt;br /&gt;
Basic strategy posted by [[User:theduck101|theduck101]] 18:12, 26 November 2011 (CEST)&lt;br /&gt;
&lt;br /&gt;
[[Traits#Shottyman|Shottyman]] is an advanced trait, allowing you to reload your equipped shotgun automatically with every move you make. To access it you need to take two levels of [[Traits#Reloader|Reloader]]. &lt;br /&gt;
&lt;br /&gt;
Obviously Shottyman is a shotgun specialist trait. It ameliorates the shotgun's biggest weakness: the need to reload after every shot. If you plan to centre your game around shotguns or are playing as an Angel of Shotgunnery then this is a very important trait. &lt;br /&gt;
&lt;br /&gt;
The first thing with Shottyman is to get out of the habit of reflexively hitting the 'r' key after every shotgun round. Instead, to get the most of Shottyman you should learn to use the reload provided by movement. &lt;br /&gt;
&lt;br /&gt;
Fire and motion is the path to Shottyman success. The tactical advantage of moving and reloading at once is that it gives you the chance to dodge in the middle of combat and return fire the next move. Knowing how to [[Dodging|dodge]] effectively is therefore critical. A good habit to get into is to use diagonal movement (pgup, pgdown, home and end keys) as your default. I won't go into the details (see [[Dodging]] for the full rundown) but the most important idea is this: never move parallel to the firing line of your enemy i.e:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            XXX&lt;br /&gt;
O************@&lt;br /&gt;
            XXX&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Moving to one of the squares marked with an X will give a chance to dodge the cacodemon's next shot. &lt;br /&gt;
&lt;br /&gt;
With Shottyman, you'll reload pretty fast (two levels of Reloader will have you reloading a normal shotgun in about 0.6s). This makes corner shooting more effective as you can fire more shots than normal before an enemy can close in. This combined with the reload and move mechanic of Shottyman gives you a nice set of options: you can reload and fire at a sergeant before he has time to fire or you can move between the sergeant and another enemy to take advantage of a little friendly fire killing the sergeant on the next move. &lt;br /&gt;
&lt;br /&gt;
For a nice increase to your damage output move in such a way that the knockback caused by your shot will push an enemy into a pool of acid/lava. This can be especially important in later levels because it will destroy the enemy corpse's making Arch-viles a little easier to deal with. &lt;br /&gt;
&lt;br /&gt;
Reducing your move time through things like tactical boots/armour greatly increases the efficacy of Shottyman. The faster you move the more shots you can fire and the quicker you can get to cover. &lt;br /&gt;
&lt;br /&gt;
Also remember to use a shotguns area of effect when targeting. Instead of aiming for a single enemy fire in the approximate midpoint of a group of enemies (as long as they are far away enough to be in the cone of spread). This deals damage to all of them at once. Manoeuvre in such a way that you deal damage to the maximum number of enemies for each round fired.&lt;br /&gt;
&lt;br /&gt;
The damage drop off for shotguns makes taking down opponents with a lot of hit-points difficult. Sometimes you'll have the ammunition to spare to keep firing into the distance. Other times a dangerous enemy will need to be killed quickly. To maximise damage you need to get in close: within about 5 squares of your target. This is especially true for the hard hitting but range impaired double shotgun. The problem is that the closer you get to an enemy the greater their chance to hit you and the lower your chance to dodge. &lt;br /&gt;
&lt;br /&gt;
There are a few ways to get around this. One is to use a combat or tactical shotgun; the damage drop off is such that 9 squares of range will still give you some bang for your, umm, buck. Otherwise you need to run.&lt;br /&gt;
&lt;br /&gt;
Running is an indispensable tactic with Shottyman. It gives you 29 moves of faster movement, increased dodging ability and reduced enemy accuracy. Even better, the downside of running, -2  accuracy, doesn't matter at all to a shotgun player since shotguns never miss. Running is therefore your Shottyman turbo mode. Medpacks and Health, Berserk, Invulnerability, Supercharge and Mega powerups all restore fatigue: think of each one of these not only as source of healing but also as 'turbo boost' for each use. &lt;br /&gt;
&lt;br /&gt;
Running allows you to charge dangerous enemies and dodge a greater percentage of their attacks. The 20% dodging bonus means you will still dodge effectively even if you're close and if you get in close you can take them out quickly. It also allows you a chance to get '''out''' of dangerous situations if you need to. Running separates the good DRL players from the rest - use it and use it well. &lt;br /&gt;
&lt;br /&gt;
The move-and-reload ability of Shottyman is especially suited to powerful shotguns that take a long time to reload. The Double Shotgun (which is the arena prize if you're playing as an Angel of Shotgunnery) becomes a lot more useful when you don't have to worry about the 2s reload time. &lt;br /&gt;
&lt;br /&gt;
Special mention should go to the [[Elephant gun]]. The elephant gun packs a punch (50% more damage than a regular shotgun) but comes with an horrendous reload time (the same as a chaingun!). Shottyman turns this lumbering beast into, if not an agile predator, then at least a predator that doesn't stop in the middle of a hunt to contemplate the meaning of life. An added bonus is that it deals out enough damage to be useful over a distance even with a normal shotgun damage decay. &lt;br /&gt;
&lt;br /&gt;
The Combat Shotgun and it's bigger brother the Tactical Shotgun with their bigger clips and range are also fine options. They are especially suited for tactical play e.g. firing round corners and radar shooting.&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Modding:Tutorial/Building_an_Episode</id>
		<title>Modding:Tutorial/Building an Episode</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Modding:Tutorial/Building_an_Episode"/>
				<updated>2025-08-11T12:35:51Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The simplest of modules are built upon a single map, a single level. While this can provide for some very unique and thrilling gameplay, it is not nearly on the same scale of DRL itself, which is a gauntlet of many levels, one after another. If you'd prefer to have a module with the structure of something longer and more challenging than a single level can produce, you're probably looking to create an episode. The purpose of this tutorial is to explain exactly how that is done.&lt;br /&gt;
&lt;br /&gt;
In order to fully explore the possibilities of an episodic module, make sure you understand the basics of modding. If nothing else, take a look at the tutorial [[Modding:Tutorial/Constructing a Map|Constructing a Map]] before continuing on.&lt;br /&gt;
&lt;br /&gt;
== Special Concept: Setting Levels ==&lt;br /&gt;
The player object comes with a custom property called &amp;quot;episode&amp;quot;. This is what determines where the player will be when they reach a certain depth. In fact, this is the majority is what is necessary to string together all the levels in an episode. This is combined with an episodic engine hook known as OnCreateEpisode to build the episode's content. Here is a simple example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
core.declare( &amp;quot;a_mod&amp;quot;, {} ) --initialize the module object&lt;br /&gt;
&lt;br /&gt;
function a_mod.OnCreateEpisode()&lt;br /&gt;
    player.episode = {}     --initialize/reset the table&lt;br /&gt;
&lt;br /&gt;
    --defines first floor as a special level&lt;br /&gt;
    player.episode[1] = { style = 1, script = &amp;quot;hells_arena&amp;quot; }&lt;br /&gt;
    --defines second floor as a random level&lt;br /&gt;
    player.episode[2] = { style = 1, number = 1, name = &amp;quot;Floor&amp;quot;, danger = 1}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following would create an episode with two levels. The first level is defined by calling a level &amp;quot;script&amp;quot;: the script used here is actually Hell's Arena from the base game. Because the map was initialized with the rest of the game (and this is not a total conversion module), it is included as part of the potential level scripts. So long as a level object has been created and initialized in your module, you are free to include any levels you want as well. (Although style does not have an effect on the level, it is necessary to include as a formality.)&lt;br /&gt;
&lt;br /&gt;
The second level is defined through level properties, rather than calling a script. When this is done, the game can initialize a level with these properties but must still produce some sort of generated content. For this, we require the OnGenerate() hook:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function a_mod.OnGenerate()&lt;br /&gt;
    Generator.reset()&lt;br /&gt;
    Generator.generate_caves_dungeon()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OnGenerate() controls the content of unscripted maps. This can be technically used to create an identical series of maps, but it is much more interesting to create maps using generator functions. Generator.reset() clears any leftover data in the generator, while Generator.generate_caves_dungeon() creates a random cave level ([[Level Type#Cave|of which you are probably familiar]]). The properties defined from OnCreateEpisode() will come into play for the purposes of determining things such as the walls, doors, floors, danger level, and so on. See [[Modding:Generator]] for a complete list of generator functions with which to play around.&lt;br /&gt;
&lt;br /&gt;
Now that we understand the basics of producing an episodic module, let us discuss a simple example that emulates that of a very old version of the game: Classic Mode.&lt;br /&gt;
&lt;br /&gt;
== Engine Hooks ==&lt;br /&gt;
&lt;br /&gt;
=== .OnCreateEpisode() ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function classic.OnCreateEpisode()&lt;br /&gt;
    local BOSS_LEVEL = 10&lt;br /&gt;
    player.episode = {}&lt;br /&gt;
  &lt;br /&gt;
    player.episode[1]     = { style = 1, script = &amp;quot;intro&amp;quot; }&lt;br /&gt;
    for i=2,BOSS_LEVEL-1 do&lt;br /&gt;
        player.episode[i] = { style = 1, number = i, name = &amp;quot;Phobos&amp;quot;, danger = i}&lt;br /&gt;
    end&lt;br /&gt;
    player.episode[10]    = { style = 3, script = &amp;quot;phobos_arena&amp;quot; }&lt;br /&gt;
	&lt;br /&gt;
    statistics.bonus_levels_count = 0&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
As before, we initialize the episode table. We've also defined the end level, coined ''BOSS_LEVEL'', as the tenth floor. The layout is fairly straightforward:&lt;br /&gt;
&lt;br /&gt;
*The very first level takes place in Phobos Base Entry. This is indicated with the script &amp;quot;intro&amp;quot;.&lt;br /&gt;
*Floors two through nine are set as randomly-generated levels. They will be named &amp;quot;Phobos 2&amp;quot;, &amp;quot;Phobos 3&amp;quot;, etc, and will have danger levels of the same number.&lt;br /&gt;
*The final level is a level script called &amp;quot;phobos_arena&amp;quot;. Although this is not included in the base game, we'll be providing this script ourselves for the purpose of this episode.&lt;br /&gt;
&lt;br /&gt;
Finally, as a matter of completeness, since there are technically no &amp;quot;special&amp;quot; levels in this episode, we set the bonus level count to zero from the statistics object. Special levels can actually be included as part of the level initialization by defining the ''special'' key: red stairs will be automatically provided on that level in addition to everything else. In either case, however, the statistics for bonus levels must be manually set.&lt;br /&gt;
&lt;br /&gt;
=== .OnGenerate() ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function classic.OnGenerate()&lt;br /&gt;
    Generator.reset()&lt;br /&gt;
    Generator.generate_tiled_dungeon()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
This function is almost identical to the one from the concepts example: the generator object is reset, and then a tiled dungeon is set for any and all unscripted (random) levels. The tiled dungeon is the de-facto level style found in DRL: it is the one that always appears on the second floor, regardless of the circumstances. Since this is a classic map, all of the levels are determined in this manner. You can, however, use some randomization within '''OnGenerate()''' to change which map is actually generated. The specifics of the randomization in the base game can be found in [[Level type]].&lt;br /&gt;
&lt;br /&gt;
=== .OnMortemPrint() ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function classic.OnMortemPrint(killedby)&lt;br /&gt;
    if killedby == &amp;quot;defeated the Mastermind&amp;quot; then&lt;br /&gt;
        killedby = &amp;quot;defeated the Cyberdemon&amp;quot;&lt;br /&gt;
    elseif killedby == nil then&lt;br /&gt;
        killedby = &amp;quot;played through the classics&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    player:mortem_print( &amp;quot; &amp;quot;..player.name..&amp;quot;, level &amp;quot;..player.explevel..&amp;quot; &amp;quot;..klasses[player.klass].name..&amp;quot;, &amp;quot;..killedby )&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''OnMortemPrint()''' is where all mortem-printing should be done, hence its name. It comes with the ''killedby'' parameter, which determines the status of the player at the time of the printing. Despite its name, ''killedby'' can produce a variety of messages, including those for winning the game. This mortem_print in particular is just like the one from the tutorial for [[Modding:Tutorial/Recreating Hell's Arena|Hell's Arena]], so it should be familiar enough to understsand already.&lt;br /&gt;
&lt;br /&gt;
Of particular note is that we require a change in the victory condition: ''killedby'' returns that the Mastermind was defeated in a standard victory, so we change it to reflect that it was the Cyberdemon instead.&lt;br /&gt;
&lt;br /&gt;
=== .OnWinGame() ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function classic.OnWinGame()&lt;br /&gt;
    ui.plot_screen([[&lt;br /&gt;
Once you beat the Cyberdemon and clean out the moon&lt;br /&gt;
base you're supposed to win, aren't you? Aren't you?&lt;br /&gt;
Where's your fat reward and ticket back home? What&lt;br /&gt;
the hell is this? It's not supposed to end this way!&lt;br /&gt;
      &lt;br /&gt;
It stinks like rotten meat but it looks like the&lt;br /&gt;
lost Deimos base. Looks like you're stuck on&lt;br /&gt;
The Shores of Hell. And the only way out is through...&lt;br /&gt;
]])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The '''OnWinGame()''' hook allows you to play around with some of the user interface commands upon winning the game. If you recall beating the base game, it's what happens immediately after killing the Spider Mastermind, but before the mortem appears. Our use of the hook simply displays a single screen of plot with the '''ui.plot_screen()''' function, which accepts a single string. You can play around with some properties here but that's better saved for '''OnMortem()'''.&lt;br /&gt;
&lt;br /&gt;
== Levels: Phobos Arena ==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Levels(&amp;quot;phobos_arena&amp;quot;,{&lt;br /&gt;
  name = &amp;quot;Phobos Arena&amp;quot;,&lt;br /&gt;
  entry = &amp;quot;Then at last he found the Phobos Arena!&amp;quot;,&lt;br /&gt;
  welcome = &amp;quot;You enter a big arena. There's blood everywhere. You hear heavy mechanical footsteps...&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
  Create = function ()&lt;br /&gt;
    Level.fill(&amp;quot;wall&amp;quot;)&lt;br /&gt;
    Level.fill(&amp;quot;floor&amp;quot;, area.FULL_SHRINKED )&lt;br /&gt;
    local scatter_area = area.new( 5,3,68,15 )&lt;br /&gt;
    local translation = {&lt;br /&gt;
        ['.'] = &amp;quot;blood&amp;quot;,&lt;br /&gt;
        ['#'] = &amp;quot;gwall&amp;quot;,&lt;br /&gt;
        ['&amp;gt;'] = &amp;quot;stairs&amp;quot;,&lt;br /&gt;
    }&lt;br /&gt;
    Level.scatter_put(scatter_area,translation, [[&lt;br /&gt;
      .....&lt;br /&gt;
      .###.&lt;br /&gt;
      .###.&lt;br /&gt;
      .###.&lt;br /&gt;
      .....&lt;br /&gt;
    ]],&amp;quot;floor&amp;quot;,12)&lt;br /&gt;
&lt;br /&gt;
    Level.flags[ LF_NOHOMING ] = true&lt;br /&gt;
    Level.scatter(area.FULL_SHRINKED,&amp;quot;floor&amp;quot;,&amp;quot;blood&amp;quot;,100)&lt;br /&gt;
    Generator.set_permanence( area.FULL )&lt;br /&gt;
    player.flags[ BF_ENTERBOSS1 ] = true&lt;br /&gt;
  end,&lt;br /&gt;
&lt;br /&gt;
  OnEnter = function ()&lt;br /&gt;
    local boss = Level.summon(&amp;quot;cyberdemon&amp;quot;)&lt;br /&gt;
    boss.flags[ BF_BOSS ] = true&lt;br /&gt;
  end,&lt;br /&gt;
  &lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
This is the level included with Classic Mode: the end-game level, Phobos Arena. This is, more or less, a replica of the original end-game level prior to version 0.9.9.5. Many of the things covered here have already been explained in the singular module tutorials, so they will not be described in detail here. This is a quick overview:&lt;br /&gt;
&lt;br /&gt;
*We start with a wall-bordered blank room, randomly add 12 pillars away from the borders, then randomly populate the rest of the level with blood.&lt;br /&gt;
*Homing phase devices will fail to work here (though there are no stairs to phase to anyway).&lt;br /&gt;
*Everything in the level is made permanent so that no walls can be destroyed&lt;br /&gt;
*The player's flags are modified so that the game knows we are on a boss level.&lt;br /&gt;
*Finally, the Cyberdemon is spawned at a random coordinate and given the boss flag, so that killing it ends the game.&lt;br /&gt;
&lt;br /&gt;
One thing not seen in previous tutorials, however, is the Level object itself. In a singular module, the level is created with the '''run()''' function: in an episodic module, levels are defined separately and called when necessary. The basic level structure is as follows:&lt;br /&gt;
&lt;br /&gt;
*Levels are technically handled with functional syntax. The identifier is placed as the first argument in this function, and a table that defines the level's properties and hooks is given as the second argument.&lt;br /&gt;
*Typical level properties are:&lt;br /&gt;
**''name'' is what the level is called, as it appears at the bottom-right.&lt;br /&gt;
**''entry'' is what appears in the mortem, signifying that you entered the level.&lt;br /&gt;
**''welcome'' is what appears in the message log as you enter the level.&lt;br /&gt;
*Hooks are added to the level, just as they would be for a singular module. Of particular note is that the '''run()''' hook is replaced with '''Create()''': they are functionally identical, but use different names due to where they are called.&lt;br /&gt;
&lt;br /&gt;
Within the module's source, this level is given its own file in a separate folder called &amp;quot;data&amp;quot;. In order for the module to access the file, a function called '''require''' is used:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
require &amp;quot;classic:data/phobos_arena&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The module's name is written before the colon, and the path from the module's root folder is written after. '''require''' assumes a .lua extension, and few other files would be useful at this time.&lt;br /&gt;
&lt;br /&gt;
== Review ==&lt;br /&gt;
Included is the main.lua, phobos_arena.lua, and the module.lua used to run the file:&lt;br /&gt;
&lt;br /&gt;
{{:Modding:Tutorial/Building an Episode/Source}}&lt;br /&gt;
&lt;br /&gt;
Source data: [http://dl.dropbox.com/u/54818507/classic.module.zip classic.module]&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Dis</id>
		<title>Dis</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Dis"/>
				<updated>2025-08-11T12:35:42Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
{{Special level|&lt;br /&gt;
level_name=Dis|&lt;br /&gt;
level_dlvl=24|&lt;br /&gt;
level_intxt=You enter the damned city of Dis...|&lt;br /&gt;
level_loottxt=Congratulations! You defeated the Spider Mastermind!|&lt;br /&gt;
level_outtxt=N/A|&lt;br /&gt;
level_itytd=[[Spider Mastermind]]|&lt;br /&gt;
level_hntr=No difference|&lt;br /&gt;
level_hmp=Do I need to go over this anymore?|&lt;br /&gt;
level_uv=Work it out, Einstein...|&lt;br /&gt;
level_n=Well YOU sure ain't a mastermind!|&lt;br /&gt;
level_loot=None|&lt;br /&gt;
level_other=This map consists of an arena as close to round as you can get in DRL, with some 4x4 pillars in a circle as cover.}}&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Strategy:Red_armor</id>
		<title>Strategy:Red armor</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Strategy:Red_armor"/>
				<updated>2025-08-11T12:35:35Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
&lt;br /&gt;
==0.9.9.5==&lt;br /&gt;
Red [[Armor]] is probably the single most important item in the entire game. It's nearly impossible to get through the last third of the game without it. With [[Baron]]s, [[Arachnotron]]s, [[Revenant]]s, [[Mancubi]], and [[Arch-vile]]s all stalking you in those last levels, the 4 damage (or 8% health, on average) it saves per hit is the difference between life and death. Moreover, the built-in 25% [[fire]] [[resistance]] (best to be capitalized on) takes the bite out of the worst three enemies. When you add in [[mod]]s, you have one of the most powerful and versatile items in the game.&lt;br /&gt;
&lt;br /&gt;
So what's the downside? -20% speed isn't fun. And the enemies you could use it against the most, Barons, wreck it the most as well. Ultimately, Red Armor is still only packing 4 protection; against Barons which can deal 20 in one hit--and because it's acid damage, armor damage is doubled--it's not pretty. Barons can reduce its durability by up to 32% in a single hit--more, if it's below 50%. The lesson: Always carry spare armor.&lt;br /&gt;
&lt;br /&gt;
Every mod goes well with this item. An agility mod brings it up to a cool -5% speed. Power mod brings it to 6 protection. Bulk gives an extra 100%--perfect against Barons--but you'll be moving slowww at -30% speed. Still, it may be your best option if you can't find any spare Reds. Technical mod is the only one that's average.&lt;br /&gt;
&lt;br /&gt;
But assemblies is where this armor really shines. Don't want to worry about carrying spares? [[Nanofiber]] it. If you find a unique mod pack, even better--[[Plate armor|+8]], [[Power armor|nearly indestructible]] protection, anyone? Of course, the best assembly of all is one of the easiest--[[fireproof armor]]. This stacks onto the native 25% fire resistance to create a 4/4, 55% fire-resisting beast of a machine. Since the triple threat of Revenant, Mancubus, and Vile (not to mention the Cyberdemon) all use fire-based attacks, this is the best armor to have in the last third of the game. It's actually more effective than 6/6 armor! (i.e., regular power-modded red armor.) I've even heard rumors of a legendary &amp;quot;cerebus armor&amp;quot;, but I'm afraid I haven't found the schematics for that one yet...&lt;br /&gt;
&lt;br /&gt;
There's nothing better than red armor. Even exotics and uniques rarely beat its combination of high protection and fire resistance. It's flaws are easily negotiable as well. If speed is your issue, slap an agility mod on it. Against Barons, always carry a spare red. (Or two.) Even better, keep a dusty blue armor around for those fights...if it gets destroyed, who cares? With Red Armor, the drlguy truly has a marine's best friend at his side. (Literally.) [[User:GrimmC|GrimmC]] 00:25, 7 January 2012 (CET)&lt;br /&gt;
&lt;br /&gt;
==0.9.9.6==&lt;br /&gt;
[[Powered Red armor]], [[Nanofiber armor]], and many other assemblies have different stats and effects than before. Additionally, the [[Plate armor]] assembly no longer exists, having been replaced by the [[Tower shield]] assembly.&lt;br /&gt;
&lt;br /&gt;
==0.9.9.7==&lt;br /&gt;
The above guide is solid but outdated and doesn't go in depth on how the assemblies work for the Red armor, so here is a more up-to-date guide.&lt;br /&gt;
&lt;br /&gt;
At base, the Red armor is still the same as it is in prior versions. 4 protection and 25% fire resistance is solid on its own as covered prior, significantly nerfing weak-to-moderate hits and giving you adequate protection against strong fire hits from the VMR (for example, it'll reduce an Arch-Vile's zap from a crushing 20 damage down to a nearly manageable 11 damage). With just a power mod and agility mod, you can get yourself an armor with 6 protection, 25% fire resistance, and only a -5% movement penalty, which is better than what many [[exotic]] and [[unique]] armors have. Such an armor would make a decent recipient of an [[onyx mod]] if you don't got one of the better exotic or assembled armors available, it's hard to do better than an APO Red armor without getting lucky with finding one of the good exotic armors. Getting a -10% movement penalty tacked on for applying a bulk mod stings and so you probably don't want to apply it to your primary Red armor if you're not playing a build that relies heavily on tanking hits, but applying it to a spare Red armor if you haven't found an onyx mod is a good idea, as Red armor with 200% durability will last a long time and is nice to have when dealing with those dastardly armor-destroying Barons.&lt;br /&gt;
&lt;br /&gt;
As for assemblies, Red armor can be used for a whopping nine of them, which will be covered now (with the required mods being in parentheses):&lt;br /&gt;
&lt;br /&gt;
*[[Fireproof armor]] (BT) - This assembly adds 30% fire resistance, in exchange for -30% melee resistance. Fireproof Red armor is one of the staple assemblies of DRL, that most players will swear by making ASAP, as getting 4 protection armor with 55% fire resistance is huge for nerfing the ever imposing threat of the VMR; with it you will reduce the Arch-vile's zap from 20 damage all the way down to 5 damage, letting a [[Scout]]/[[Technician]] with base HP take up up to 10 hits before dying instead of just 3, while a [[Marine]] can take up to 12 hits. Having this armor is great assurance when fighting these enemies that can normally wipe out a third or more of your health in one hit, no more will you have to worry about a Mancubus suddenly killing you because you stepped into one's sight. It severely nerfs the Cyberdemon's rockets too, with them averaging 5 or less damage per hit, and rarely being able to deal more than 10 damage against this armor, very helpful for builds that don't have [[Strategy:Dodgemaster|Dodgemaster]] nor are running [[Strategy:Berserker|Berserker]]. Not to mention it's also great for [[rocket jump]]ing, reducing the self harm from rocket jumps down to 1-3 damage without any reduction in knockback. The cheap mod cost and a guaranteed Red armor at [[Phobos Anomaly]] coming right when VMR are about to start showing up on UV difficulty makes this an imperative assembly to build. The -30% melee resistance is an unfortunate downside, which will hurt if you get hit by stronger melee enemies like Barons, but considering how much more dangerous those fire attacks are, it's certainly a well-worth tradeoff for most builds. Melee builds are the primary ones who won't want to make this assembly; aside from the obvious reason that they will actively get in melee range of enemies, the +60% resistances from [[berserk]] and VMR being great triggers for Berserker means they'll suffice enough with normal modded Red armor, or in the case of [[Strategy:Malicious Blades|Malicious Blades]], that master gives them +50% fire resistance at all times as long as they got a blade in their prepared slot, so normal-modded Red armor is pretty much always better for them (either with berserk or Malicious Blades, a base Red armor will reduce an Arch-vile's zap to ''1 damage''). &lt;br /&gt;
&lt;br /&gt;
*[[Ballistic armor]] (AT) - This is essentially the reverse of Fireproof armor, with this assembly adding 30% melee resistance to any armor (in addition to +30% bullet and shrapnel resistance) while subtracting -30% fire resistance. Given how much the importance of fire resistance was stressed just above, you can obviously figure this assembly is often not worth using on Red armor, and if you do desire a very strong melee armor (such as for trying to beat the [[Unholy Cathedral]] without having [[Strategy:Brute|Brute]] investment, or when you're going to be taking a huge amount of melee damage throughout the game from going for something like the Strongman [[badges]]), the [[Duelist armor]], [[Ballistic armor]], or even the [[Medical armor]] would be better choices with their already built-in melee resistance this assembly will compound on. That said, if you cannot find any of those armors and do really need something better than a P-modded Red armor for melee, using Red armor for this assembly would do you better than the other standard armors, as that 4 protection will see substantial mileage on top of the resistance, and since it'll only go down to -5% fire resistance after the assembly, you won't get instantly vaporized if you get caught by the VMR in Ballistic Red armor.&lt;br /&gt;
&lt;br /&gt;
*[[Nanofiber armor]] (BP) - This assembly gives any armor it's applied to infinite durability, in exchange for cutting its protection and all its resistance in half. Having infinite durability on your armor is very nice, but that's a very steep cost to pay that is usually not worth it; on Red armor you would get an armor with 2 protection and 12% fire resistance, a pitiful amount that will barely make a dent against surviving VMR attacks (it would reduce an Arch-vile zap from 20 damage down to 16, meaning you'll barely survive only one more hit from them than usual), while you'll still have that stiff -20% movement penalty. The main appeal of the assembly is insuring you'll always have a spare armor no matter what, regardless of how badly you get beaten up and how badly the RNG decides to deprive you of [[armor shard]]s to repair your armor. Generally though, bulk mods on your spare armors should be enough to get you through when your frontline armor gets damaged, and if you're getting hit so much that even B-modded Red armors can't last, you should be reevaluating your tactics as you are probably going to die if you're taking that much damage in Nanofiber armor. If you haven't found an onyx mod though and really want infinite durability armor above all else, Red armor is one of the best bases for this assembly and better than the other standard armors. It should be stated this assembly is situationally a lot more useful in [[Strategy:Angel of Purity|Angel of Purity]], where the restriction on powerups makes you unable to restore your armor through armor shards and [[Megasphere]]s, or for any run where tanking an extreme amount of damage is unavoidable, such as again with runs for the aforementioned Strongman badges. Even in these cases, you should still hold off on Nanofibering your first Red armor until at least after [[Hell's Armory]]/[[Deimos Lab]], where you'll have a good chance to get an onyx or [[nano mod]] that will completely obsolete the need for any Nanofiber armor.&lt;br /&gt;
&lt;br /&gt;
*[[Fireshield]] (BTO) - An assembly that only the Red armor can be used for, which is an extreme take on the aforementioned Fireproof armor; in exchange for the same ingredients plus an Onyx mod, you'll get an armor with the same 4 protection and -20% movement speed as Red armor, but with '''''95% fire resistance'''''. This armor will reduce every single fire attack in the game down to 1 damage no matter how strong it is, the only fire protection better than this is the complete fire immunity from the Inquisitor Set (which considering how rare just finding one of [[Malek's Armor]] or [[Nyarlaptotep's Boots]] is, let alone both together in anything other than in an [[Strategy:Archangel of 666|Archangel of 666]] run, the Fireshield will be the more realistically obtainable best defense against fire). This sounds like a no-brainer assembly, but with it requiring an onyx mod and not having infinite durability, there is a huge opportunity cost to it. Furthermore, this armor is a shield, which means it cannot be repaired without a Megasphere, that you might go an entire game without ever finding one of. With 200% durability it can last a while, especially if you are only taking VMR attacks in it that will only ever deal 1 damage, but if other enemies start hitting it, especially Barons, you'll find this armor you spent your onyx mod gone before you know it. You'll be better off just using the onyx mod normally on Red armor, or if you want strong fire protection that lasts forever, make a Fireproof Red armor after getting Whizkid 2 and then applying the onyx mod to it; it would require the same ingredients as the Fireshield and you'll already need Whizkid to make a Fireshield. You should only consider this assembly if you find an onyx mod late in the game after having exhausted the modding slots of your main armors and have no other good use for it, while being late in the game also means it'll much more likely last the rest of the way regardless of Megasphere luck.&lt;br /&gt;
&lt;br /&gt;
*[[Tower shield]] (PO) - Another assembly that only the Red armor can be used for, which gets you an armor with a massive 12 protection, the highest protection value any armor can get outside of a P-modded Cybernano [[Cybernetic Armor]] (which only Technicians can even make), and the [[Berserker Armor]] when you're at low HP. It has a massive -50% movement penalty however, and -90% knockback, so you'll really struggle to move at all in this armor. It additionally has no resistances, and so it won't protect as well from strong hits as you would expect; the Arch-vile zap we been using as a benchmark throughout this will deal 8 damage to you in this armor, a big reduction from its 20 damage but still quite worse than what simple Fireproof Red armor achieves, and barely better than P-modded Red armor. Worst of all however, like the aforementioned Fireshield, this requires an onyx mod, and it is a shield, so it can't be repaired without Megaspheres. The 150% durability is decent, but this will not last long if you try to make any active use of this armor, especially when the slowness of the armor will force you to take hits you wouldn't have otherwise. Like with the Fireshield, only consider this assembly if you find an onyx mod late and have no good armor to use it on.&lt;br /&gt;
&lt;br /&gt;
*[[Power armor]] (PN) - An assembly that can only be used by the standard armors, which includes Red armor. This assembly adds a point of protection, doubles the armor's base resistances, adds +25% melee resistance, removes the movement penalty altogether (in effect being +20% movement speed for Red armor), and has regenerating durability. Red armor is unequivocally the best base of the standard armors for this assembly, as you'll get 5 protection and a very valuable 50% fire resistance, on top of the other benefits mentioned. Powered Red armor effectively fuses the fire defense of Fireproof Red armor with the melee defense of Ballistic Red armor, while also completely addressing the Red armor's movement weakness; combined with the regenerating durability, this is very good armor that you can possibly subsist solely on for the entire game. The only drawback is the -25% knockback penalty, which will nerf rocket jumping, while this armor's great fire resistance and regenerating durability makes it ideal rocket jumping armor otherwise. However, this assembly does require a coveted nano mod, which will often be better used on [[Nanomanufacture ammo]], [[Nano-shrapnel]], or [[Antigrav boots]]; the former two assemblies allow you to create some gamebreaking weapons, while Antigrav boots give you some gamebreaking movement speed. As good as Powered Red armor is, it's not a game-changer in the ways those other nano assemblies are, and so often it's not advised to be your first or second or maybe not even your third choice to use a nano mod on. The main exception would be if you're playing a build that can't or isn't getting Whizkid, or is not getting Whizkid until late into the game; in the former case, a single nano mod on a weapon is likely not doing much except for maybe a [[Plasma rifle]] or [[BFG 9000]], and in the latter case, you may not even survive long enough to get Whizkid to build those other nano assemblies (while there's also the argument of getting more immediate use from Powered Red armor for many floors rather than not getting anything from the nano mod but clogging inventory until those final few floors).&lt;br /&gt;
&lt;br /&gt;
*[[Nanofiber skin armor]] (PPN) - An assembly that can be applied to any armor, which adds  +25% resistance to all damage types on top of the armor's base resistances, in addition to regenerating durability and being indestructible, but you'll never be able to remove the armor for the rest of the run. Applying this assembly to Red armor will get you regenerating armor that protects nearly as well against fire attacks as Fireproof Red armor, while giving you some much needed resistance against Barons' acid balls and the hard-to-protect against plasma enemies. However, aside from what was said above about using a nano mod for armor, the caveat of not being able to ever remove this armor is a huge caveat; you'll be committed to this armor for the rest of this run, and if you're in a situation where it's not up to snuff, then you're screwed. As is, Nanofiber skin Red armor is certainly good armor, but not so much to be comfortable to be stuck with it; 25% resistance with 4 protection against acid and plasma attacks isn't all that much (Baron balls will still be averaging at least 5 damage and can do up to 11, Arachnotrons can still do more than 1 damage per plasma bolt with max damage rolls, which adds up quick with their rapid-fire volleys, and stronger plasma enemies are still hurting you), and you'll still have the Red armor's -20% movement speed. If you want to commit to this assembly, the [[Energy-shielded vest]], [[Phaseshift armor]], [[Cybernetic Armor]] (if you're a Technician), or even the [[Duelist armor]] are better, and if you don't have those, you would still be better off with Powered Red armor; it doesn't give you that bit of extra protection against acid and plasma, but it's much faster with no movement penalty, and you'll still have the option to remove it for other armor, such as one with actual good resistance against those acid and plasma enemies.&lt;br /&gt;
&lt;br /&gt;
*[[Cybernano armor]] (PPNO) - An assembly that can be applied to any armor, which gives it +4 protection, in addition to infinite durability, but you'll never be able to remove the armor for the rest of the run. The +4 protection is big, double what you can get from a power mod, and you'll still have the option to add one more mod after, whether another power mod to go +6 on protection, or an agility mod to make you faster. This armor is similar to Nanofiber skin armor in the amount of extra defense you get (with Cybernano Red armor being slightly better against hits that deal less than 14 damage, while Nanofiber skin Red armor is slightly better against hits that deal more than 17 damage, and against plasma damage those values are instead 6 and 9 damage respectively), with the perk of infinite durability meaning you won't need to worry about a sudden big beating temporarily damaging your armor. However, it still has all the same problems; using a nano mod for armor is a big opportunity cost, this assembly is a huge commitment, and the Red armor is not an ideal base to be hitching your entire run on this assembly with. Additionally, the Powered Red armor is still better if you want to use your nano mod on armor and you haven't found a better exotic armor to use as a base, as the effective +20% movement speed, protecting better against fire attacks, and the ability to swap it out for other armor is better than 3 more protection points (not to mention that you would then be free to use the onyx mod elsewhere if you actually managed to get both it and a nano mod in the same run).&lt;br /&gt;
&lt;br /&gt;
*[[Cerberus armor]] (PPTA) - An assembly that can be applied to any armor, which regardless of what base you use, results in an armor with 0 protection, -30% movement speed, and -30% knockback, but has an astounding 70% resistance to fire and acid attacks, a great 50% resistance against plasma attacks, and will inherent its physical resistances and durability from the base armor. Now Cerberus armor is very good, with the right assembly base you can potentially get yourself an armor with 50% resistance or more against every damage type in the game, but Red armor is among the worst bases for it; with Red armor having no resistance against any physical damage, using it will net you a baseline Cerberus armor that will leave you effectively naked in melee and against formers, while it has no durability perks like the [[Onyx armor]] netting you infinite durability Cerberus armor without the need for an onyx mod. Even [[Green armor]] would be a better base, as it does have something extra to give the Cerberus armor at least with its meager 15% resistance to bullet and shrapnel. You should hold off on assembling Cerberus armor until you get one of the good exotic armors for it, but baseline Cerberus armor is still pretty good (protecting you nearly as well against fire attacks as Fireproof Red armor, while protecting you much better against Barons and plasma enemies), and so if you cannot find any of the good exotic armors for it, using a Red armor for the base will still be acceptable.&lt;br /&gt;
&lt;br /&gt;
Overall, the Red armor tends to be a good choice for the basic armor assemblies, particularly Fireproof Red armor, but for the more intricate assemblies it can be used for, it's either usually not worth it or clearly outclassed by other armors, or in the case of Power armor, it is great but the opportunity cost is usually too high to recommend it. And on its own the Red armor is far from the best armor, there are exotic and unique armors with a lot more potential than it, but it's certainly the most reliable armor when those better armors require luck to find. [[User:Omega Tyrant|Omega Tyrant]] ([[User talk:Omega Tyrant|talk]]) 23:32, 11 August 2023 (UTC)&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Modding:generator_API_(0.9.9.7)</id>
		<title>Modding:generator API (0.9.9.7)</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Modding:generator_API_(0.9.9.7)"/>
				<updated>2025-08-11T12:35:30Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''This page is currently under construction.''&lt;br /&gt;
&lt;br /&gt;
The generator holds all of the ever-present functions used to create the random maps in DRL. It also contains a variety of helper functions, many of them useful if not vital to the creation of intricate and meticulous game design.&lt;br /&gt;
&lt;br /&gt;
== API ==&lt;br /&gt;
&lt;br /&gt;
Please note that the type &amp;quot;integer&amp;quot; indicates an numeric value without a decimal part.  It does not indicate the range of acceptable values.&lt;br /&gt;
&lt;br /&gt;
The argument type &amp;quot;CellID&amp;quot; may be the numeric or string ID of a cell.&lt;br /&gt;
&lt;br /&gt;
The argument type &amp;quot;CellSet&amp;quot; may be the numeric ID, string ID, or a list of numeric and/or string IDs.&lt;br /&gt;
&lt;br /&gt;
The argument type &amp;quot;Flags&amp;quot; expects a list of [[Modding:Constants|flag constants]] of the indicated type.  &lt;br /&gt;
&lt;br /&gt;
An argument name in [square brackets] is an optional one.  The function description will indicate how the function operates if it is omitted.&lt;br /&gt;
&lt;br /&gt;
=== Generator API Function List ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;border: 2px solid darkred; border-spacing: 0; font-size: 90%; margin: 0.25em 0.5em;&amp;quot;&lt;br /&gt;
 ! colspan=&amp;quot;2&amp;quot; style=&amp;quot;background: darkred; color: yellow; font-size: 120%; text-align: center&amp;quot;|'''Generator Interface - Functions'''&lt;br /&gt;
 {{Table2Col&lt;br /&gt;
  |es=background: #333; &lt;br /&gt;
  |c1=font-weight:bold; text-align:right; vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |c2=padding:0px 2px;&lt;br /&gt;
  ||'''[[#Basic Cell Handling Functions|Basic Cell Handling Functions]]'''&lt;br /&gt;
  |{{modarg|integer}}|{{moddef|list|get_cell|dot||Coord|loc}}&lt;br /&gt;
  |{{modarg|string}}|{{moddef|list|get_cell_id|dot||Coord|loc}}&lt;br /&gt;
  |{{modarg|integer}}|{{moddef|list|fast_get_cell|dot||integer|x|integer|y}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|set_cell|dot||Coord|loc|CellID|what}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|fast_set_cell|dot||integer|x|integer|y|integer|what}}&lt;br /&gt;
  ||'''[[#Map Checking Functions|Map Checking Functions]]'''&lt;br /&gt;
  |{{modarg|integer}}|{{moddef|list|around|dot||Coord|where|CellSet|what}}&lt;br /&gt;
  |{{modarg|integer}}|{{moddef|list|cross_around|dot||Coord|where|CellSet|what}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|is_empty|dot||Coord|where|Flags|reqs}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|is_empty_area|dot||Area|where|Flags|reqs}}  &lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|scan|dot||Area|where|CellID|good}}&lt;br /&gt;
  ||'''[[#Map Searching Functions|Map Searching Functions]]'''&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|drop_coord|dot||Coord|where|Flags|reqs}}&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|find_coord|dot||CellSet|what|Area|[where]}}&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|random_coord|dot||Area|[where]}}&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|find_random_coord|dot||CellSet|what|Area|[where]}}&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|find_empty_coord|dot||CellSet|what|Flags|reqs|Area|[where]}}&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|random_empty_coord|dot||Flags|reqs|Area|[where]}}&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|find_random_empty_coord|dot||CellSet|what|Flags|reqs|Area|[where]}}&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|safe_empty_coord|dot||Area|[where]}}&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|standard_empty_coord|dot}}&lt;br /&gt;
  ||'''[[#Advanced Cell Handling Functions|Advanced Cell Handling Functions]]'''&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|fill|dot||CellID|what|Area|[where]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|fill_pattern|dot||Area|where|boolean|horiz|Table|line1|Table|[line2]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|fill_edges|dot||CellID|what}}&lt;br /&gt;
  |{{modarg|Table}}|{{moddef|list|each|dot||CellID|what|Area|[where]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|set_blood|dot||Area|[where]|boolean|[value]|CellID|[what]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|set_permanence|dot||Area|[where]|boolean|[value]|CellID|[what]}}&lt;br /&gt;
  |{{modarg|Table}}|{{moddef|list|cell_set|dot||CellSet|cells}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|restore_walls|dot||CellID|wallCell|boolean|keepFluids}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|plot_line|dot||Coord|where|boolean|horiz|CellID|cell|CellSet|block}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|plot_lines|dot||Coord|where|Area|larea|boolean|horiz|CellID|cell|CellSet|block}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|scatter|dot||Area|where|CellID|good|CellID|fill|integer|count}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|scatter_blood|dot||Area|where|CellID|[good]|integer|count}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|scatter_put|dot||Area|where|Table|translation|string|tile|CellID|good|integer|count}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|transmute|dot||CellID|to|CellSet|from|Area|[where]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|transmute_marker|dot||Flag|marker|CellID|To|Area|[where]}}&lt;br /&gt;
  ||'''[[#Tile Handling Functions|Tile Handling Functions]]'''&lt;br /&gt;
  |{{modarg|Table}}|{{moddef|list|create_translation|dot||Table|code}}&lt;br /&gt;
  |{{modarg|Tile}}|{{moddef|list|tile_new|dot||string|map|Table|translation}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|tile_place|dot||Coord|where|Tile|what}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|place_tile|dot||Table|translation|string|tile|integer|x|integer|y}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|place_dungen_tile|dot||Table|code|Tile|tile|Coord|where}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|place_symmetry_quad|dot||string|tile|Table|translation}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|place_proto_map|dot||Coord|where|string|proto_map|string|proto_key|Table|code}}&lt;br /&gt;
  ||'''[[#Room Handling Functions|Room Handling Functions]]'''&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|add_room|dot||Area|room|string|[class]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|add_rooms|dot}}&lt;br /&gt;
  |{{modarg|Room}}|{{moddef|list|get_room|dot||integer|min_size|integer|max_x|integer|max_y|integer|max_area|string|[class]}}&lt;br /&gt;
  |{{modarg|integer, integer}}|{{moddef|list|get_endpoints|dot||Coord|where|boolean|horiz|CellSet|what}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|handle_rooms|dot||integer|count|boolean|no_monsters}}&lt;br /&gt;
  ||'''[[#Generation Algorithm Functions|Generation Algorithm Functions]]'''&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|run_drunkard_walk|dot||Area|where|Coord|start|integer|steps|CellID|fill|CellSet|[ignore]|boolean|[stop_at_edge]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|drunkard_walks|dot||integer|amount|integer|steps|CellID|fill|CellSet|[ignore]|boolean|[stop_at_edge]|Area|[where]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|contd_drunkard_walks|dot||integer|amount|integer|steps|CellID|fill|CellSet|edges1|CellSet|edges2|CellSet|[ignore]|boolean|[stop_at_edge]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|warehouse_fill|dot||CellSet|fill|Area|where|integer|size|integer|count|integer|special_chance|CellSet|special}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|place_blob|dot||Coord|start|integer|size|CellID|cell}}&lt;br /&gt;
  ||'''[[#Generator Helper Functions|Generator Helper Functions]]'''&lt;br /&gt;
  |{{modarg|&amp;lt;value&amp;gt;, &amp;lt;value&amp;gt;}}|{{moddef|list|roll_pair|dot||Table|list}}&lt;br /&gt;
  |{{modarg|integer}}|{{moddef|list|being_weight|dot}}&lt;br /&gt;
  |{{modarg|integer}}|{{moddef|list|item_amount|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|horiz_river|dot||CellID|cell|integer|width|boolean|[bridge]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|vert_river|dot||CellID|cell|integer|width|boolean|bridge|integer|position}}&lt;br /&gt;
{{moddef|list|vert_river|dot||CellID|cell|integer|width|boolean|bridge|Coord|position}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_rivers|dot||boolean|allow_horiz|boolean|allow_more}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_fluids|dot||Area|[where]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_barrels|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_stairs|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_special_stairs|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|place_player|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|run|dot||Generator|gen}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|reset|dot}}&lt;br /&gt;
  ||'''[[#Dungeon Generation Functions|Dungeon Generation Functions]]'''&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_tiled|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|maze_dungeon|dot||CellID|floor|CellID|wall|integer|granularity|integer|tries|integer|min_size|integer|max_size}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_caves_dungeon|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_caves_2_dungeon|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_lava_dungeon|dot}}&lt;br /&gt;
  ||'''[[#Event Handler Functions|Event Handler Functions]]'''&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|roll_event|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|setup_flood_event|dot||integer|direction|integer|step|CellID|cell}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|setup_deadly_air_event|dot||integer|step}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|setup_explosion_event|dot||integer|step|integer|size|integer|dice|integer|[content]}}&lt;br /&gt;
{{moddef|list|setup_explosion_event|dot||integer|step|Table|size|integer|dice|integer|[content]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|setup_targeted_event|dot||integer|step}}&lt;br /&gt;
  |}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Basic Cell Handling Functions ===&lt;br /&gt;
;{{moddef|desc|get_cell|dot|integer|Coord|loc}}&lt;br /&gt;
Gets the Numeric ID (NID) of the [[Modding:Cell|cell]] at a given map position.&lt;br /&gt;
:''loc'': The coordinates of the cell to get.&lt;br /&gt;
:'''Returns''': The NID of the cell.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|get_cell_id|dot|string|Coord|loc}}&lt;br /&gt;
Gets the ID of the [[Modding:Cell|cell]] at a given map position.&lt;br /&gt;
:''loc'': The coordinates of the cell to get.&lt;br /&gt;
:'''Returns''': The string ID of the cell.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|fast_get_cell|dot|integer|integer|x|integer|y}}&lt;br /&gt;
Gets the Numeric ID (NID) of the [[Modding:Cell|cell]] at a given map position.&lt;br /&gt;
:''x'': The X position of the cell to get.&lt;br /&gt;
:''y'': The Y position of the cell to get.&lt;br /&gt;
:'''Returns''': The NID of the cell.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|set_cell|dot||Coord|loc|CellID|what}}&lt;br /&gt;
Assigns a [[Modding:Cell|cell]] to a map position.&lt;br /&gt;
:''loc'': The coordinates of the position to set.&lt;br /&gt;
:''what'': The ID of the cell to assign to the position.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|fast_set_cell|dot||integer|x|integer|y|integer|what}}&lt;br /&gt;
Assigns a [[Modding:Cell|cell]] to a map position.&lt;br /&gt;
:''x'': The X position of the cell to set.&lt;br /&gt;
:''y'': The Y position of the cell to set.&lt;br /&gt;
:''what'': The NID (string IDs not allowed) of the cell to assign to the position.&lt;br /&gt;
----&lt;br /&gt;
=== Map Checking Functions ===&lt;br /&gt;
;{{moddef|desc|around|dot|integer|Coord|where|CellSet|what}}&lt;br /&gt;
Checks the positions adjacent to a location (including diagonally adjacent) and returns the number of cells that match one of the indicated cell IDs.&lt;br /&gt;
:''where'': The coordinate to check around.  The coordinate sent in this way is not checked, only adjacent cells are.&lt;br /&gt;
:''what'': The cell(s) to check for.&lt;br /&gt;
:'''Returns''': The number of cells (from 0 to 8) that matched one of the ''what'' cell IDs.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|cross_around|dot|integer|Coord|where|CellSet|what}}&lt;br /&gt;
Checks the positions adjacent to a location (but not diagonally adjacent) and returns the number of cells that match one of the indicated cell IDs.&lt;br /&gt;
:''where'': The coordinates to check around.  The coordinate sent in this way is not checked, only adjacent cells are.&lt;br /&gt;
:''what'': The cell(s) to check for.&lt;br /&gt;
:'''Returns''': The number of cells (from 0 to 4) that matched one of the ''what'' cell IDs.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|is_empty|dot|boolean|Coord|where|Flags|reqs}}&lt;br /&gt;
Checks to see if the indicated cell is &amp;quot;empty&amp;quot;, defining &amp;quot;empty&amp;quot; based on a list of criteria.&lt;br /&gt;
:''where'': The position to check.&lt;br /&gt;
:''reqs'': A list of EmptyFlags (named numeric constants that start with EF_) indicating which types of objects or properties the position cannot have.  For example, if the flag EF_NOBEINGS is sent, the function only returns true if the map position does not contain a [[Modding:Being|being]].  See [[Modding:Constants#Empty_Flags]] for more information.&lt;br /&gt;
:'''Returns''': ''True'' if the cell satisfies all of the conditions indicated in ''reqs'', ''False'' otherwise.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|is_empty_area|dot|boolean|Area|where|Flags|reqs}}&lt;br /&gt;
Checks to see if the indicated area is &amp;quot;empty&amp;quot;, defining &amp;quot;empty&amp;quot; based on a list of criteria.&lt;br /&gt;
:''where'': The area to check.&lt;br /&gt;
:''reqs'': A list of EmptyFlags (named numeric constants that start with EF_) indicating which types of objects or properties the area cannot have.  For example, if the flag EF_NOBEINGS is sent, the function only returns true if the area does not contain a [[Modding:Being|being]].  See [[Modding:Constants#Empty_Flags]] for more information.&lt;br /&gt;
:'''Returns''': ''True'' if every cell in the area satisfies all of the conditions indicated in ''reqs'', ''False'' otherwise.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|scan|dot|boolean|Area|where|CellID|good}}&lt;br /&gt;
Checks to see if the entire area is filled with a certain cell.&lt;br /&gt;
:''where'': The area to check.&lt;br /&gt;
:''good'': The cell to look for.&lt;br /&gt;
:'''Returns''': ''True'' if all cells in the area are ''good'', ''False'' otherwise.&lt;br /&gt;
----&lt;br /&gt;
=== Map Searching Functions ===&lt;br /&gt;
;{{moddef|desc|drop_coord|dot|Coord|Coord|where|Flags|reqs}}&lt;br /&gt;
Finds the nearest &amp;quot;empty&amp;quot; coordinate to a given coordinate, defining &amp;quot;empty&amp;quot; based on a list of criteria.&lt;br /&gt;
:''where'': The coordinate to try.  If this coordinate is &amp;quot;empty&amp;quot;, this coordinate will be returned.&lt;br /&gt;
:''reqs'': A list of EmptyFlags (named numeric constants that start with EF_) indicating which types of objects or properties the coordinate cannot have.  For example, if the flag EF_NOBEINGS is sent, the function only returns a coordinate that does not contain a [[Modding:Being|being]].  See [[Modding:Constants#Empty_Flags]] for more information.&lt;br /&gt;
:'''Returns''': The nearest coordinate the satisfies the criteria.  If the supplied coordinate meets the criteria, that coordinate will be returned.  If not a nearby, random, coordinate will be checked. &lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|find_coord|dot|Coord|CellSet|what|Area|[where]}}&lt;br /&gt;
Searches the map for the first coordinate containing one of the indicated cell IDs.&lt;br /&gt;
:''what'': The cell(s) to search for.&lt;br /&gt;
:''where'': ''Optional.'' The area to restrict the search to.  If omitted, the coordinate can be picked from anywhere on the map.&lt;br /&gt;
:'''Returns''': The coordinates of the first position that contains one of the ''what'' cell IDs.  The map is checked row by row starting from the top, going from left to right across each row.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|random_coord|dot|Coord|Area|[where]}}&lt;br /&gt;
Searches for a random coordinate within the specified area.&lt;br /&gt;
:''where'': ''Optional.'' The area to restrict the coordinate to.  If omitted, the coordinate can be picked from anywhere on the map.&lt;br /&gt;
:'''Returns''': A random coordinate.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|find_random_coord|dot|Coord|CellSet|what|Area|[where]}}&lt;br /&gt;
Searches for a random coordinate within the specified area that contains one of the specified cell IDs.&lt;br /&gt;
:''what'': The cell(s) to search for.&lt;br /&gt;
:''where'' : ''Optional.'' The area to restrict the search to.  If omitted, the coordinate can be picked from anywhere on the map.&lt;br /&gt;
:'''Returns''': A random coordinate that meets the supplied criteria.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|find_empty_coord|dot|Coord|CellSet|what|Flags|reqs|Area|[where]}}&lt;br /&gt;
Searches the map for the first &amp;quot;empty&amp;quot; coordinate containing one of the indicated cell IDs, defining &amp;quot;empty&amp;quot; based on a list of criteria.&lt;br /&gt;
:''what'': The cell(s) to search for.&lt;br /&gt;
:''reqs'':  A list of EmptyFlags (named numeric constants that start with EF_) indicating which types of objects or properties the coordinate cannot have.  For example, if the flag EF_NOBEINGS is sent, the function only returns a coordinate that does not contain a [[Modding:Being|being]].  See [[Modding:Constants#Empty_Flags]] for more information.&lt;br /&gt;
:''where'': ''Optional.'' The area to restrict the search to.  If omitted, the coordinate can be picked from anywhere on the map.&lt;br /&gt;
:'''Returns''': The coordinates of the first position that meets the supplied criteria.  The map is checked row by row starting from the top, going from left to right across each row.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|random_empty_coord|dot|Coord|Flags|reqs|Area|[where]}}&lt;br /&gt;
Searches the map for a random coordinate that is &amp;quot;empty&amp;quot;, defining &amp;quot;empty&amp;quot; based on a list of criteria.&lt;br /&gt;
:''reqs'': A list of EmptyFlags (named numeric constants that start with EF_) indicating which types of objects or properties the random coordinate cannot have.  For example, if the flag EF_NOBEINGS is sent, the function only returns a coordinate that does not contain a [[Modding:Being|being]].  See [[Modding:Constants#Empty_Flags]] for more information.&lt;br /&gt;
:''where'': ''Optional.'' The area to restrict the search to.  If omitted, the coordinate can be picked from anywhere on the map.&lt;br /&gt;
:'''Returns''': A random coordinate that meets the supplied criteria.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|find_random_empty_coord|dot|Coord|CellSet|what|Flags|reqs|Area|[where]}}&lt;br /&gt;
Searches the map for a random &amp;quot;empty&amp;quot; coordinate containing one of the indicated cell IDs, defining &amp;quot;empty&amp;quot; based on a list of criteria.&lt;br /&gt;
:''what'': The cell(s) to search for.&lt;br /&gt;
:''reqs'':  A list of EmptyFlags (named numeric constants that start with EF_) indicating which types of objects or properties the random coordinate cannot have.  For example, if the flag EF_NOBEINGS is sent, the function only returns a coordinate that does not contain a [[Modding:Being|being]].  See [[Modding:Constants#Empty_Flags]] for more information.&lt;br /&gt;
:''where'': ''Optional.'' The area to restrict the search to.  If omitted, the coordinate can be picked from anywhere on the map.&lt;br /&gt;
:'''Returns''': A random coordinate that meets the supplied criteria.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|random_square|dot|Coord|CellSet|what}}&lt;br /&gt;
Searches for a random 3x3 area containing only specified cells.&lt;br /&gt;
:''what'': The cell(s) to search for.&lt;br /&gt;
:'''Returns''': The center coordinate of the random 3x3 area.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|safe_empty_coord|dot|Coord|Area|[where]}}&lt;br /&gt;
Searches for a random coordinate that meets certain predetermined criteria.&lt;br /&gt;
&lt;br /&gt;
The function will try to find a coordinate that does not contain a being, item, staircase, wall, harmful terrain, spawning restrictions (cells marked with LF_NOSPAWN), and is more than 5 spaces from the player (EF_NOBEINGS, EF_NOITEMS, EF_NOSTAIRS, EF_NOBLOCK, EF_NOHARM, EF_NOSPAWN, and EF_NOSAFE).  If a valid space isn't found, the function will ignore distance from the player (EF_NOSAFE).  If a valid space still can't be found, the function will ignore stairs and harmful terrain (EF_NOSTAIRS and EF_NOHARM).&lt;br /&gt;
:''where'': ''Optional.'' The area to restrict the initial pass to.  If a valid coordinate is not found within the area after ignoring stairs and harmful terrain, the search is restarted and expanded automatically to the entire map.  If omitted, the entire map will be searched.&lt;br /&gt;
:'''Returns''': A random coordinate that meets the criteria.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|standard_empty_coord|dot|Coord}}&lt;br /&gt;
Searches for a random coordinate that meets certain predetermined criteria.&lt;br /&gt;
&lt;br /&gt;
The function will search for a coordinate that does not contain a being, item, staircase, wall, harmful terrain, or spawning restrictions (EF_NOBEINGS, EF_NOITEMS, EF_NOSTAIRS, EF_NOBLOCK, EF_NOHARM, and EF_NOSPAWN).&lt;br /&gt;
:'''Returns''': A random coordinate that meets the criteria.&lt;br /&gt;
----&lt;br /&gt;
=== Advanced Cell Handling Functions ===&lt;br /&gt;
;{{moddef|desc|fill|dot||CellID|what|Area|[where]}}&lt;br /&gt;
Fills an area of the map with a given cell.&lt;br /&gt;
:''what'': The cell to fill with.&lt;br /&gt;
:''where'': ''Optional.'' The area to fill with the cell.  If omitted, the entire map will be filled.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|fill_pattern|dot||Area|where|boolean|horiz|string|Table|line1|Table|[line2]}}&lt;br /&gt;
Fills an area of the map with a pattern of cells.&lt;br /&gt;
:''where'': The area to fill.&lt;br /&gt;
:''horiz'': If ''True'', the pattern will fill each row left to right, then move to the next row down in the area.  If ''False'', the pattern will fill each column top to bottom, then move to the next column right in the area. &lt;br /&gt;
:''line1'': The pattern to fill with.  If the pattern is shorter than the area size, the pattern will loop.  The pattern does not restart at the end of a row or column.&lt;br /&gt;
:''line2'': ''Optional.'' If given, each time the end of row (if ''horiz'' is ''True'') or column (if ''horiz'' is ''False'') is reached, the function will switch to filling with the other pattern.  That is, the first row will use ''line1'' then the second will use ''line2'', then the third will use ''line1'' again, etc.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|fill_edges|dot||CellID|what}}&lt;br /&gt;
Fills the edges of the map with the given cell.&lt;br /&gt;
:''what'': The cell to fill with.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|each|dot|Table|CellID|what|Area|[where]}}&lt;br /&gt;
Searches for a cell and returns a table containing every location it was found.&lt;br /&gt;
:''what'': The cell to search for.&lt;br /&gt;
:''where'': ''Optional.'' The area to restrict the search to.&lt;br /&gt;
:'''Returns''': A table containing a list of [[Modding:Coord|Coord]] objects.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|set_blood|dot||Area|[where]|boolean|[value]|CellID|[what]}}&lt;br /&gt;
Adds blood to the map or removes blood from it.&lt;br /&gt;
:''where'': ''Optional.'' The area to affect.  If omitted, the entire map will selected.&lt;br /&gt;
:''value'': ''Optional.'' ''True'' adds blood.  ''False'' removes it.  If omitted, the default is to add blood.&lt;br /&gt;
:''what'': ''Optional.'' If provided, only locations containing the given cell are affected.  If omitted, all cells in the area are affected.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|set_permanence|dot||Area|[where]|boolean|[value]|CellID|[what]}}&lt;br /&gt;
Makes cell permanent or removes their permanence.&lt;br /&gt;
:''where'': ''Optional.'' The area to affect.  If omitted, the entire map will be selected.&lt;br /&gt;
:''value'': ''Optional.'' ''True'' adds permanence.  ''False'' removes it.  If omitted, the default is to add permanence.&lt;br /&gt;
:''what'': ''Optional.'' If provided, only locations containing the given cell are affected.  If omitted, wall cells (which includes crate cells) are affected.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|cell_set|dot|Table|CellSet|cells}}&lt;br /&gt;
Creates a cell group.&lt;br /&gt;
:''cells'': A list of cells to add to the group.&lt;br /&gt;
:'''Returns''': A cell group table.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|restore_walls|dot||CellID|wallCell|boolean|keepFluids}}&lt;br /&gt;
Fixes the edge walls of the map.&lt;br /&gt;
:''wallCell'': The cell to fill the edge of the map with.&lt;br /&gt;
:''keepFluids'': ''True'' to maintain any fluid tiles on the edge of the map.  ''False'' to overwrite them.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|plot_line|dot||Coord|where|boolean|horiz|CellID|cell|CellSet|block}}&lt;br /&gt;
Splits an area into two at the indicated location.&lt;br /&gt;
:''where'': The starting point.&lt;br /&gt;
:''horiz'': ''True'' draws along the indicated X position of the ''where'' coordinate.  ''False'' draws along the indicated Y position of the ''where'' coordinate.&lt;br /&gt;
:''cell'': The cell that will be used to split the area.&lt;br /&gt;
:''block'': The cell(s) that block the line plotting.  The drawn line will stop before hitting a coordinate with one of these cells.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|plot_lines|dot||Coord|where|Area|larea|boolean|horiz|CellID|cell|CellSet|block}}&lt;br /&gt;
Splits an area into two at the indicated location.&lt;br /&gt;
:''where'': The starting point.&lt;br /&gt;
:''larea'': The boundaries of the line.  The line will not extend past the edge of the area.&lt;br /&gt;
:''horiz'': ''True'' draws along the indicated X position of the ''where'' coordinate.  ''False'' draws along the indicated Y position of the ''where'' coordinate.&lt;br /&gt;
:''cell'': The cell that will be used to split the area.&lt;br /&gt;
:''block'': The cell(s) that block the line plotting.  The drawn line will stop before hitting a coordinate with one of these cells.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|scatter|dot||Area|where|CellID|good|CellID|fill|integer|count}}&lt;br /&gt;
Randomly places a certain cell around the map.&lt;br /&gt;
:''where'': The area to scatter the cell in.&lt;br /&gt;
:''good'': Only this locations with this cell will be changed by the function.&lt;br /&gt;
:''fill'': The cell to scatter around the area.&lt;br /&gt;
:''count'': The number to attempt to place.  If the chosen location is not ''good'', then it will not change it.  The final number placed may be less than ''count'' (or even 0), but never more.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|scatter_blood|dot||Area|where|CellID|[good]|integer|count}}&lt;br /&gt;
Randomly adds blood in an area.&lt;br /&gt;
:''where'': The area to scatter blood in.&lt;br /&gt;
:''good'': ''Optional.'' If defined, only locations with this cell will have blood added.  If omitted, any location my have blood added.&lt;br /&gt;
:''count'': The number of attempts.  On each attempt, a random cell in the area will be chosen to have blood added.  The number of cell that will end up bloody may be less than ''count'' (or even 0), but never more.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|scatter_put|dot||Area|where|Table|translation|string|tile|CellID|good|integer|count}}&lt;br /&gt;
Randomly adds a specified tile (a defined arrangement of cells) around the map.&lt;br /&gt;
:''where'': The area to scatter the tile in.  The tiles will only be placed in locations entirely within the area.&lt;br /&gt;
:''translation'': A table with to be used with the ''tile'' argument.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:''tile'': A multi-line string, one row of the tile per line, that lays out the arrangment of the cells.  Refer to this (will be linked soon) for more information&lt;br /&gt;
:''good'': Only locations with this cell will be valid for the tile placement.  If any coordinates of the selected placement area are not ''good'', the tile will not be placed at that location.&lt;br /&gt;
:''count'': The number of tiles to try to place.  The placement will continue until this many have been placed, or 10,000 attempts have been made, whichever comes first.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|transmute|dot||CellID|to|CellSet|from|Area|[where]}}&lt;br /&gt;
Changes all of one cell on the map to another cell.&lt;br /&gt;
:''to'': The cell that will replace the existing cells.&lt;br /&gt;
:''from'': The cell(s) that will be replaced.&lt;br /&gt;
:''where'': ''Optional.'' If specified, only cells in the area are changed.  If omitted, the function will change cells across the entire map.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|transmute_marker|dot||Flag|marker|CellID|To|Area|[where]}}&lt;br /&gt;
Changes all positions on the map that have a specified LightFlag (a named constant starting with &amp;quot;LF&amp;quot;, no underscore) to another cell.&lt;br /&gt;
:''marker'': The LightFlag to check for.  Only cells with this flag will be changed.&lt;br /&gt;
:''to'': The cell that will replace the existing cells.&lt;br /&gt;
:''where'': ''Optional.'' If specified, only cells in the area are changed.  If omitted, the function will change cells across the entire map.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Tile Handling Functions ===&lt;br /&gt;
;{{moddef|desc|create_translation|dot|Table|Table|code}}&lt;br /&gt;
Parses a translation table.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:''code'': The translation table.&lt;br /&gt;
:'''Returns''': A parsed translation table.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|tile_new|dot|Tile|string|map|Table|translation}}&lt;br /&gt;
Creates a new tile object.&lt;br /&gt;
:''map'': A multi-line string containing the arrangement of the tile using the ''translation'' to convert the characters to cells.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:''translation'': A table with to be used with the ''map'' argument.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:'''Returns''': The new tile object.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|tile_place|dot||Coord|where|Tile|what}}&lt;br /&gt;
Places the cells of the tile on the map.&lt;br /&gt;
:''where'': The coordinate that the upper-left of the tile should reside at.&lt;br /&gt;
:''what'': The tile object that will be placed.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|place_tile|dot||Table|translation|string|tile|integer|x|integer|y}}&lt;br /&gt;
Combines the tile_new and tile_place functions together, by placing a tile using a string and translation table.&lt;br /&gt;
:''translation'': A table with to be used with the ''tile'' argument.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:''tile'': A multi-line string containing the arrangement of the tile using the ''translation'' to convert the characters to cells.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:''x'': The X position that the tile will be placed at.&lt;br /&gt;
:''y'': The Y position that the tile will be placed at.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|place_dungen_tile|dot||Table|code|Tile|tile|Coord|where}}&lt;br /&gt;
Places an entire tile, including beings and items in the translation, on the map.&lt;br /&gt;
:''code'': The translation table.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:''tile'': A multi-line string containing the arrangement of the tile using the ''translation'' to convert the characters to cells and indicate the positions of the beings and items.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:''where'': The coordinate the tile will be placed at.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|place_symmetry_quad|dot||string|tile|Table|translation}}&lt;br /&gt;
Takes a tile object and places it in all four corners.  The tile object should be setup for the upper left corner and will be mirrored to the other corners.  The tiles are placed one space from the map edge.&lt;br /&gt;
:''tile'': A multi-line string containing the arrangement of the tile using the ''translation'' to convert the characters to cells and indicate the positions of the beings and items.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:''translation'': The translation table.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|place_proto_map|dot||Coord|where|string|proto_map|string|proto_key|Table|code}}&lt;br /&gt;
Creates a map using multiple tile sets.&lt;br /&gt;
:''where'': The upper-left position of the map where the tiles will be layout from.&lt;br /&gt;
:''proto_map'': A string indicating the arrangement of the different pieces of the map.  e.g., &amp;quot;ABCD&amp;quot;, will lay out 4 different tiles with A on the far left and D on the far right.&lt;br /&gt;
:''proto_key'': A table containing, for each character in ''proto_map'', a table of the possible tiles for that section.&lt;br /&gt;
:''code'': The translation table for all the tile possibilities.  Refer to this (will be linked soon) for more information.  All tiles use the same translation table.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Room Handling Functions ===&lt;br /&gt;
;{{moddef|desc|add_room|dot||Area|room|string|[class]}}&lt;br /&gt;
Marks an area that can become a special room.&lt;br /&gt;
:''room'': The area of the room.  This includes the walls.&lt;br /&gt;
:''class'': ''Optional.'' A string used to denote which room generators can be used on this room.  If omitted, the class used is &amp;quot;closed&amp;quot;.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|add_rooms|dot}}&lt;br /&gt;
Finds all the areas that can be rooms on a map and adds them to the appropriate meta-map tables.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|get_room|dot|Room|integer|min_size|integer|max_x|integer|max_y|integer|max_area|string|class}}&lt;br /&gt;
Selects a room given certain criteria.&lt;br /&gt;
:''min_size'': The smallest X and Y dimensions the room can be.&lt;br /&gt;
:''max_x'': The maximum width of the room.&lt;br /&gt;
:''max_y'': The maximum height of the room.&lt;br /&gt;
:''max_area'': The largest area the room can be.&lt;br /&gt;
:''class'': ''Optional.'' The string denoting which room classes are valid for this room generator.  If omitted, &amp;quot;any&amp;quot; is used, which does not restrict the selection of rooms.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|get_endpoints|dot|integer, integer|Coord|where|boolean|horiz|CellSet|what}}&lt;br /&gt;
Finds the ends of a line of cells.&lt;br /&gt;
:''where'': The starting coordinate.&lt;br /&gt;
:''horiz'': ''True'' checks horizontally.  ''False'' checks vertically.&lt;br /&gt;
:''what'': The cell(s) that make up the line to check.  The functions stops at the first cell '''not''' in this list.&lt;br /&gt;
:'''Returns''': Two integers.  If ''horiz'' is ''True'', these are the X positions the line stops at.  If ''horiz'' is ''False'', these are the Y positions the line stops at.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|handle_rooms|dot||integer|count|boolean|no_monsters}}&lt;br /&gt;
Runs the rooms selection and setup process for a map.&lt;br /&gt;
:''count'': The number of rooms to attempt to place.&lt;br /&gt;
:''no_monsters'': ''True'' will exclude room generators that place monsters.  ''False'' will not.&lt;br /&gt;
----&lt;br /&gt;
=== Generation Algorithm Functions ===&lt;br /&gt;
;{{moddef|desc|run_drunkard_walk|dot||Area|where|Coord|start|integer|steps|CellID|fill|CellSet|[ignore]|boolean|[stop_at_edge]|Area|where}}&lt;br /&gt;
Runs an algorithm that walks to random adjacent spaces.&lt;br /&gt;
:''where'': The area that the algorithm will run in.  If the algorithm tries to leave the area, it will stop early or will be pushed back in the area (''stop_at_edge'' will determine which of these happen).&lt;br /&gt;
:''start'': The location the algorithm will begin at.&lt;br /&gt;
:''steps'': The number of steps the algorithm will take.  The number of spaces covered by the algorithm will be at most this number.&lt;br /&gt;
:''fill'': The cell that will be placed at each location the algorithm hits.&lt;br /&gt;
:''ignore'': ''Optional.'' If specified, the algorithm will not place the ''fill'' cell in any location that has one of the cell(s) specified.  If omitted, no locations are ignored.&lt;br /&gt;
:''stop_at_edge'': ''Optional.'' If ''True'', the algorithm will end early if it moves past the end of the area.  If ''False'', the algorithm will clamp to the area (any moves to outside the area get moved back in the area).  If omitted, the default is to clamp.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|drunkard_walks|dot||integer|amount|integer|steps|CellID|fill|CellSet|[ignore]|boolean|[stop_at_edge]|Area|[where]}}&lt;br /&gt;
Runs multiple &amp;quot;drunken walk&amp;quot; algorithms.&lt;br /&gt;
:''amount'': The number of times to perform the algorithm.&lt;br /&gt;
:''steps'': The number of steps each run of the algorithm will take.  The number of spaces covered by the algorithm will be at most the ''amount'' times the number of ''steps''.&lt;br /&gt;
:''fill'': The cell that will be placed at each location the algorithm hits.&lt;br /&gt;
:''ignore'': ''Optional.'' If specified, the algorithm will not place the ''fill'' cell in any location that has one of the cell(s) specified.  If omitted, no locations are ignored.&lt;br /&gt;
:''stop_at_edge'': ''Optional.'' If ''True'', the algorithm will end early if it moves past the end of the area.  If ''False'', the algorithm will clamp to the area (any moves to outside the area get moved back in the area).  If omitted, the default is to clamp.&lt;br /&gt;
:''where'': ''Optional.'' The area the algorithm will run in.  If the algorithm tries to leave the area, it will stop early or will be pushed back in the area (''stop_at_edge'' will determine which of these happen).  If omitted, the default is entire area minus the very edge.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|contd_drunkard_walks|dot||integer|amount|integer|steps|CellID|fill|CellSet|edges1|CellSet|edges2|CellSet|[ignore]|boolean|[stop_at_edge]}}&lt;br /&gt;
Runs multiple &amp;quot;drunken walk&amp;quot; algorithms starting at a space that doesn't have certain cells around it.&lt;br /&gt;
:''amount'': The number of times to perform the algorithm.&lt;br /&gt;
:''steps'': The number of steps each run of the algorithm will take.  The number of spaces covered by the algorithm will be at most the ''amount'' times the number of ''steps''.&lt;br /&gt;
:''fill'': The cell that will be placed at each location the algorithm hits.&lt;br /&gt;
:''edges1'': The algorithm will not start on a space with a cell listed here next to it.&lt;br /&gt;
:''edges2'': The algorithm will not start on a space with a cell listed here next to it.&lt;br /&gt;
:''ignore'': ''Optional.'' If specified, the algorithm will not place the ''fill'' cell in any location that has one of the cell(s) specified.  If omitted, no locations are ignored.&lt;br /&gt;
:''stop_at_edge'': ''Optional.'' If ''True'', the algorithm will end early if it moves past the end of the area.  If ''False'', the algorithm will clamp to the area (any moves to outside the area get moved back in the area).  If omitted, the default is to clamp.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|warehouse_fill|dot||CellID|fill|Area|where|integer|[size]|integer|[count]|integer|[special_chance]|CellID|[special]}}&lt;br /&gt;
Fills an area with random squares of cells.&lt;br /&gt;
:''fill'': The cell(s) to use for each square.  If a list is given, one is chosen at random for each square.&lt;br /&gt;
:''where'': The area to fill.&lt;br /&gt;
:''size'': ''Optional.'' The size of the squares to use. If omitted, the default is 2.&lt;br /&gt;
:''count'': ''Optional.'' The number of attempts. If omitted, the default is 50.&lt;br /&gt;
:''special_chance'': ''Optional.'' A number indicating the probability of using a special list of cells to fill the square with instead of the ''fill'' list.  The roll used for the chance is based on the ''size'' parameter.  A number from 1 to (100 * ''size'') is chosen for each square and if the roll is less than the special_chance number, the ''special'' cell set is used to fill the square instead. If omitted, all squares will be filled from the ''fill'' set.&lt;br /&gt;
:''special'': ''Optional.'' The list of cells to use if the special set is to be used, based on ''special_chance''. If omitted, all squares will be filled from the ''fill'' set.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|place_blob|dot||Coord|start|integer|size|CellID|cell}}&lt;br /&gt;
Fills an area by expanding to random edge coordinates.&lt;br /&gt;
:''start'': The position to start the blob at.&lt;br /&gt;
:''size'': The number of spaces to expand the blob to.&lt;br /&gt;
:''cell'': The cell to fill the blob area with.&lt;br /&gt;
----&lt;br /&gt;
=== Generator Helper Functions ===&lt;br /&gt;
;{{moddef|desc|roll_pair|dot|&amp;lt;value&amp;gt;, &amp;lt;value&amp;gt;|Table|list}}&lt;br /&gt;
Takes a list of values of any type and returns two different values randomly from the list.&lt;br /&gt;
:''list'': The list to choose from.&lt;br /&gt;
:'''Returns''': Two different values.  If the list only contains one choice, it will be returned, but only once.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|being_weight|dot}}&lt;br /&gt;
Gets the total danger level for the current dungeon level.&lt;br /&gt;
'''Returns''': The danger level for the current dungeon level.  This value is calcuated using the current difficulty and ''level.danger_level''.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|item_amount|dot}}&lt;br /&gt;
Gets the number of items to drop for the current dungeon level.&lt;br /&gt;
'''Returns''': The number of items to drop for the current dungeon level.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|horiz_river|dot||CellID|cell|integer|width|boolean|[bridge]}}&lt;br /&gt;
Places a horizontal river on the map.&lt;br /&gt;
:''cell'': The cell to use for the river.  It does not have to be a fluid cell.&lt;br /&gt;
:''width'': The width of the river.&lt;br /&gt;
:''bridge'': ''Optional.'' If ''True'', a 2 space wide bridge will be placed at a random coordinate on the river.  If ''False'', no bridge will be placed.  If omitted, the default is to not place a bridge.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|vert_river|dot||CellID|cell|integer|width|boolean|bridge|integer|[position]}}&lt;br /&gt;
;{{moddef|desc|vert_river|dot||CellID|cell|integer|width|boolean|bridge|Coord|[position]}}&lt;br /&gt;
Places a vertical river on the map.&lt;br /&gt;
:''cell'': The cell to use for the river.  It does not have to be a fluid cell.&lt;br /&gt;
:''width'': The width of the river.&lt;br /&gt;
:''bridge'': ''Optional.'' If ''True'', a 2 space wide bridge will be placed at a random coordinate on the river.  If ''False'', no bridge will be placed.  If omitted, the default is to not place a bridge.&lt;br /&gt;
:: NOTE: Because of a bug, a bridge will always be placed on the river, even if this value is set to ''False'' or omitted.&lt;br /&gt;
:''position'':  A coordinate or an integer.  If an integer is supplied, this is the X position of the river's left edge.  If a coordinate is supplied, the river will start at this coordinate.  If omitted, the river's left edge will be selected from between X = 19 to 58.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_rivers|dot||boolean|allow_horiz|boolean|allow_more}}&lt;br /&gt;
Creates rivers based on normal DRL river generation.&lt;br /&gt;
:''allow_horiz'': ''True'' allows horizontal rivers to be generated.  ''False'' will prevent the generation of horizontal rivers.&lt;br /&gt;
:''allow_more'': ''True'' allows multiple vertical rivers.  ''False'' will prevent more than one vertical river from being placed.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_fluids|dot||Area|[where]}}&lt;br /&gt;
Creates fluids based on normal DRL fluid generation.&lt;br /&gt;
:''where'': ''Optional.'' The area to generate fluids in.  If omitted, the area used will be the entire map minus the very edge.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_barrels|dot}}&lt;br /&gt;
Creates barrels based on normal DRL barrel generation.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_stairs|dot}}&lt;br /&gt;
Creates the normal staircase based on normal DRL stair generation.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_special_stairs|dot}}&lt;br /&gt;
Creates the special staircase based on normal DRL special stair generation.  Whether a special staircase is placed depends on the level.special_exit value.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|place_player|dot}}&lt;br /&gt;
Places the player on a random empty space.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|run|dot||Generator|gen}}&lt;br /&gt;
Runs a generator object.  These are stored in the generators table.&lt;br /&gt;
:''gen'': The generator object to run.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|reset|dot}}&lt;br /&gt;
Resets the map.&lt;br /&gt;
----&lt;br /&gt;
=== Dungeon Generation Functions ===&lt;br /&gt;
;{{moddef|desc|generate_tiled|dot}}&lt;br /&gt;
Creates a tiled dungeon, also known as a &amp;quot;normal&amp;quot; dungeon.  This only creates the layout, it does not place beings, items, stairs, barrels, or the player.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|maze_dungeon|dot||CellID|floor|CellID|wall|integer|granularity|integer|tries|integer|min_size|integer|max_size}}&lt;br /&gt;
Creates a maze dungeon.  This only creates the layout, it does not place beings, items, stairs, barrels, or the player.&lt;br /&gt;
:''floor'': The cell to use for the floor of the maze.&lt;br /&gt;
:''wall'': The cell to use for the wall of the maze.&lt;br /&gt;
:''granularity'': This denotes the size of the maze's paths.&lt;br /&gt;
:''tries'': Number of attempts to place a new wall in the maze.&lt;br /&gt;
:''min_size'': The smallest possible size of a wall.&lt;br /&gt;
:''max_size'': The largest possible size of a wall.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_caves_dungeon|dot}}&lt;br /&gt;
Runs the generation script for the cave dungeon.  This is an all inclusive function, it also places all beings and items.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_caves_2_dungeon|dot}}&lt;br /&gt;
Runs the generation script for the cave-city dungeon.  This is an all inclusive function, it also places all beings and items.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_lava_dungeon|dot}}&lt;br /&gt;
Runs the generation script for the lava dungeon.  This is an all inclusive function, it also places all beings and items.&lt;br /&gt;
----&lt;br /&gt;
=== Event Handler Functions ===&lt;br /&gt;
;{{moddef|desc|roll_event|dot}}&lt;br /&gt;
Picks an event from the events table and sets it up.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|setup_flood_event|dot||integer|direction|integer|step|CellID|cell}}&lt;br /&gt;
Runs the setup script for the flood event.&lt;br /&gt;
:''direction'': Use 1 to flood from the left.  Use -1 to flood from the right.&lt;br /&gt;
:''step'': Number of turns (0.1 second intervals) between each flood step.&lt;br /&gt;
:''cell'': The cell to flood with.  This does not have to be a fluid cell.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|setup_deadly_air_event|dot||integer|step}}&lt;br /&gt;
Runs the setup script for the deadly air event.&lt;br /&gt;
:''step'': Number of turns between each &amp;quot;chill&amp;quot; (loss of HP).&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|setup_explosion_event|dot||integer|step|integer|size|integer|dice|integer|[content]}}&lt;br /&gt;
;{{moddef|desc|setup_explosion_event|dot||integer|step|Table|size|integer|dice|integer|[content]}}&lt;br /&gt;
Runs the setup script for the explosion event.&lt;br /&gt;
:''step'': Number of turns between each explosion.&lt;br /&gt;
:''size'': Either a number or a table of two numbers.  Indicates the size of each explosion.  If a table is supplied, the size is randomly chosen between the range supplied each time an explosion is created.&lt;br /&gt;
:''dice'': Number of d6 dice to use for the damage roll.&lt;br /&gt;
:''content'': ''Optional.'' The content to place in any space where the damage to a space is more than 20 points.  If omitted, nothing will placed.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|setup_targeted_event|dot||integer|step}}&lt;br /&gt;
Runs the setup script for the targeting event.&lt;br /&gt;
:''step'': Number of turns between each monster teleport.&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Modding:being_blueprint_(0.9.9.7)</id>
		<title>Modding:being blueprint (0.9.9.7)</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Modding:being_blueprint_(0.9.9.7)"/>
				<updated>2025-08-11T12:35:05Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The being [[Modding:blueprint|blueprint]] is used to define new beings.&lt;br /&gt;
&lt;br /&gt;
== Blueprint ==&lt;br /&gt;
&lt;br /&gt;
Being blueprints are registered with the ''register_being'' procedure. Registered blueprints are stored in a global Lua table called ''beings''.&lt;br /&gt;
&lt;br /&gt;
{{drltable|Being Blueprint|3|{{Table3Col&lt;br /&gt;
  |es=background: #333;&lt;br /&gt;
  |c1=font-family:monospace; text-align:right; vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |c2=vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |c3=padding:0px 2px;&lt;br /&gt;
  |id             |{{modarg|string}}|The unique identifier used by the engine for this being. Passed as the first argument when registering a blueprint.&lt;br /&gt;
  |&amp;lt;u&amp;gt;name&amp;lt;/u&amp;gt;    |{{modarg|string}}|This is the being's name.&lt;br /&gt;
  |name_plural    |{{modarg|string}}|This is the being's pluralized name. This defaults to the being's the name with an &amp;quot;s&amp;quot; appended.&lt;br /&gt;
  |sound_id       |{{modarg|being}}|If included the being will search for sounds bound to this id instead of its own.&lt;br /&gt;
  |&amp;lt;u&amp;gt;ascii&amp;lt;/u&amp;gt;   |{{modarg|string}}|This is the being's picture in console mode. It should be a single character string.&lt;br /&gt;
  |&amp;lt;u&amp;gt;color&amp;lt;/u&amp;gt;   |{{modarg|Color}}|This is the being's color in console mode.&lt;br /&gt;
  |&amp;lt;u&amp;gt;sprite&amp;lt;/u&amp;gt;  |{{modarg|Sprite}}|This is the being's sprite in graphical mode.&lt;br /&gt;
  |coscolor       |{{modarg|ColorSet}}|This is a graphical mode filter that can be used to add color to specific sprites.&lt;br /&gt;
  |glow           |{{modarg|ColorSet}}|This is a graphical mode filter that can be used to give a sprite a colored glow.&lt;br /&gt;
  |overlay        |{{modarg|ColorSet}}|This is a graphical mode filter that can be used to subtract color from any sprite.&lt;br /&gt;
  |hp             |{{modarg|integer}}|This is the being's hpmax and starting hp. The default is 10.&lt;br /&gt;
  |armor          |{{modarg|integer}}|This is the being's armor bonus. The default is 0.&lt;br /&gt;
  |attackchance   |{{modarg|integer}}|This is the being's attackchance. The default is 75.&lt;br /&gt;
  |todam          |{{modarg|integer}}|This is the being's todam bonus. The bonus applies only to melee attacks. The default is 0.&lt;br /&gt;
  |tohit          |{{modarg|integer}}|This is the being's tohit bonus. The default is 0.&lt;br /&gt;
  |tohitmelee     |{{modarg|integer}}|This is the being's tohitmelee bonus. The default is 0.&lt;br /&gt;
  |speed          |{{modarg|integer}}|This is the being's speed. The maximum allowed speed is 255. The default is 100.&lt;br /&gt;
  |vision         |{{modarg|integer}}|This is the being's vision bonus. The default is 0, meaning the same vision as the player.&lt;br /&gt;
  |&amp;lt;u&amp;gt;min_lev&amp;lt;/u&amp;gt; |{{modarg|integer}}|This is a [[Monster Generation|monster generation]] parameter.&lt;br /&gt;
  |max_lev        |{{modarg|integer}}|This is a [[Monster Generation|monster generation]] parameter. The default is 10000.&lt;br /&gt;
  |corpse         |{{modarg|cell}}|The determines the corpse left by the being. Instead of passing in a cell directly you can pass a boolean ''true'' which will make the engine automatically create and assign an appropriate being corpse. You can also pass in ''false'' or leave this field blank to specify no corpse.&lt;br /&gt;
  |&amp;lt;u&amp;gt;danger&amp;lt;/u&amp;gt;  |{{modarg|integer}}|This is a [[Monster Generation|monster generation]] parameter.&lt;br /&gt;
  |&amp;lt;u&amp;gt;weight&amp;lt;/u&amp;gt;  |{{modarg|integer}}|This is a [[Monster Generation|monster generation]] parameter.&lt;br /&gt;
  |xp             |{{modarg|integer}}|This is the being's expvalue. By default, it is &amp;lt;font-family: monospace&amp;gt;3xD&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;+20, where D is the being's &amp;lt;u&amp;gt;danger&amp;lt;/u&amp;gt; value (above).&lt;br /&gt;
  |bulk           |{{modarg|integer}}|This parameter is unused. The default is 100.&lt;br /&gt;
  |flags          |{{modarg|Being Flag}}|This parameter is an array of being flags which will be used by all beings of this type by default.&lt;br /&gt;
  |&amp;lt;u&amp;gt;ai_type&amp;lt;/u&amp;gt; |{{modarg|AI}}|This determines the being's AI.&lt;br /&gt;
  |res_bullet   |{{modarg|integer}}|This is the being's resistance to bullet damage. The default is 0.&lt;br /&gt;
  |res_melee    |{{modarg|integer}}|This is the being's resistance to melee damage. The default is 0.&lt;br /&gt;
  |res_shrapnel |{{modarg|integer}}|This is the being's resistance to shrapnel damage. The default is 0.&lt;br /&gt;
  |res_acid     |{{modarg|integer}}|This is the being's resistance to acid damage. The default is 0.&lt;br /&gt;
  |res_fire     |{{modarg|integer}}|This is the being's resistance to fire damage. The default is 0.&lt;br /&gt;
  |res_plasma   |{{modarg|integer}}|This is the being's resistance to plasma damage. The default is 0.&lt;br /&gt;
  |&amp;lt;u&amp;gt;desc&amp;lt;/u&amp;gt;      |{{modarg|string}}|This is the description of the being displayed in the 'more information' view.&lt;br /&gt;
  |&amp;lt;u&amp;gt;kill_desc&amp;lt;/u&amp;gt; |{{modarg|string}}|If included this being will have a special kill description in the mortem.&lt;br /&gt;
  |kill_desc_melee  |{{modarg|string}}|If included this being will have a special melee kill description in the mortem.&lt;br /&gt;
  |weapon |{{modarg|Item Blueprint}}|You can inline an item blueprint here and it will be registered for you.  Items defined this way are always natural ranged weapons that never drop and have no ammo.  It will even be equippedly automatically for you.&lt;br /&gt;
  |OnCreate     |{{modarg|function}}|&lt;br /&gt;
  |OnAction     |{{modarg|function}}|&lt;br /&gt;
  |OnAttacked   |{{modarg|function}}|&lt;br /&gt;
  |OnDie        |{{modarg|function}}|&lt;br /&gt;
  |OnDieCheck   |{{modarg|function}}|&lt;br /&gt;
  |OnPickupItem |{{modarg|function}}|&lt;br /&gt;
  |}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Engine Hooks ==&lt;br /&gt;
&lt;br /&gt;
{{drltable|Being Hooks|2|{{Table2Col&lt;br /&gt;
  |es=background: #333;&lt;br /&gt;
  |c1=font-family:monospace; text-align:right; vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |c2=padding:0px 2px;&lt;br /&gt;
  |{{modarg|void}}   |[[#being_OnCreate    |OnCreate]] ({{modarg|being}} self)&lt;br /&gt;
  |{{modarg|void}}   |[[#being_OnAction    |OnAction]] ({{modarg|being}} self)&lt;br /&gt;
  |{{modarg|void}}   |[[#being_OnAttacked  |OnAttacked]] ({{modarg|being}} self)&lt;br /&gt;
  |{{modarg|void}}   |[[#being_OnDie       |OnDie]] ({{modarg|being}} self, {{modarg|boolean}} overkill)&lt;br /&gt;
  |{{modarg|boolean}}|[[#being_OnDieCheck  |OnDieCheck]] ({{modarg|being}} self, {{modarg|boolean}} overkill)&lt;br /&gt;
  |{{modarg|void}}   |[[#being_OnPickupItem|OnPickupItem]] ({{modarg|being}} self, {{modarg|item}} item)&lt;br /&gt;
  |}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Anchor|being_OnCreate}}&lt;br /&gt;
'''OnCreate'''({{modarg|being}} self)&lt;br /&gt;
:This is called when the being is created. Usually inventory and equipment get added here but many more adjustments are possible.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_OnAction}}&lt;br /&gt;
'''OnAction'''({{modarg|being}} self)&lt;br /&gt;
:This is called at the beginning of a being's turn. It is never called more than once per tick and the player, sadly, does not use this.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_OnAttacked}}&lt;br /&gt;
'''OnAttacked'''({{modarg|being}} self)&lt;br /&gt;
:This is called when a being is attacked and is usually only used by being AIs. It is not possible to determine the attacker.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_OnDie}}&lt;br /&gt;
'''OnDie'''({{modarg|being}} self, {{modarg|boolean}} overkill)&lt;br /&gt;
:This is called when the being dies. ''overkill'' is true if the being was gibbed.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_OnDieCheck}}&lt;br /&gt;
'''OnDieCheck'''({{modarg|being}} self, {{modarg|boolean}} overkill) &amp;amp;rarr; '''boolean'''&lt;br /&gt;
:This is called right before a being would normally die. Returning '''false''' will prevent the death, giving the being a minimum of 1 hp. ''overkill'' is true if the being was gibbed.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_OnPickupItem}}&lt;br /&gt;
'''OnPickupItem'''({{modarg|being}} self, {{modarg|item}} item)&lt;br /&gt;
:This is called when a being picks up an item. It is only used in DRL for statistical purposes.&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Manual:sound.lua</id>
		<title>Manual:sound.lua</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Manual:sound.lua"/>
				<updated>2025-08-11T12:34:56Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This file allows you to manage the sounds that are played in DRL.  &lt;br /&gt;
Sounds are organized by object, and each object has multiple sounds that can be changed depending on the action (for instance, one sound for an enemy taking damage, another for it dying).  &lt;br /&gt;
In many cases, sounds for similar objects (like fuel barrels and acid barrels) can be changed separately.  &lt;br /&gt;
The default sounds and the descriptions of each entry in the sound.lua (or soundhq.lua for the high quality version) are in the tables below, in the order they appear in the file (except for the being sounds, which are moved after everything else).&lt;br /&gt;
&lt;br /&gt;
== Item Default Sounds ==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; align=&amp;quot;left&amp;quot; cell-padding=&amp;quot;1ex&amp;quot; | Object&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; align=&amp;quot;left&amp;quot; cell-padding=&amp;quot;1ex&amp;quot; | Action&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; align=&amp;quot;left&amp;quot; cell-padding=&amp;quot;1ex&amp;quot; | Description&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; align=&amp;quot;left&amp;quot; cell-padding=&amp;quot;1ex&amp;quot; | Default Sound (LQ)&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; align=&amp;quot;left&amp;quot; cell-padding=&amp;quot;1ex&amp;quot; | Default Sound (HQ)&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|menu&lt;br /&gt;
|change&lt;br /&gt;
|Sound played when highlighting a menu option.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspstop.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|pick&lt;br /&gt;
|Sound played when selecting a menu option (clicking on/pressing enter).&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspistol.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|cancel&lt;br /&gt;
|Sound played when backing up in menus (escape).&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsswtchx.wav&lt;br /&gt;
|-&lt;br /&gt;
|barrel (Barrel of Fuel)&lt;br /&gt;
|move&lt;br /&gt;
|Sound played when a fuel barrel is successfully pushed.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsstnmov.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|movefail&lt;br /&gt;
|Sound played when attempting to push a fuel barrel into a blocked space.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsnoway.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|explode&lt;br /&gt;
|Sound played when a fuel barrel blows up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbarexp.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|barrela (Barrel of Acid)&lt;br /&gt;
|move&lt;br /&gt;
|Sound played when an acid barrel is successfully pushed.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsstdmov.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|movefail&lt;br /&gt;
|Sound played when attempting to push an acid barrel into a blocked space.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsnoway.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|explode&lt;br /&gt;
|Sound played when an acid barrel blows up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbarexp.wav&lt;br /&gt;
|-&lt;br /&gt;
|barreln (Barrel of Napalm)&lt;br /&gt;
|move&lt;br /&gt;
|Sound played when a napalm barrel is successfully pushed.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsstdmov.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|movefail&lt;br /&gt;
|Sound played when attempting to push a napalm barrel into a blocked space.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsnoway.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|explode&lt;br /&gt;
|Sound played when a napalm barrel blows up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbarexp.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|door&lt;br /&gt;
|open&lt;br /&gt;
|Sound played when a door is opened.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbdopn.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|close&lt;br /&gt;
|Sound played when a door is closed.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbdcls.wav&lt;br /&gt;
|-&lt;br /&gt;
|teleport&lt;br /&gt;
|use&lt;br /&gt;
|Sound played when the player or an enemy steps on a teleporter.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dstelept.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|lever&lt;br /&gt;
|use&lt;br /&gt;
|Sound played when a lever is pulled.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsswtchn.wav&lt;br /&gt;
|-&lt;br /&gt;
|gib&lt;br /&gt;
|&lt;br /&gt;
|Sound played when an enemy is gibbed (overkilled).&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsslop.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|shglobe (Small Health Globe)&lt;br /&gt;
|powerup&lt;br /&gt;
|Sound played when a Small Health Globe is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsgetpow.wav&lt;br /&gt;
|-&lt;br /&gt;
|lhglobe (Large Health Globe)&lt;br /&gt;
|powerup&lt;br /&gt;
|Sound played when a Large Health Globe is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsgetpow.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|scglobe (Supercharge Globe)&lt;br /&gt;
|powerup&lt;br /&gt;
|Sound played when a Supercharge Globe is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsgetpow.wav&lt;br /&gt;
|-&lt;br /&gt;
|iglobe (Invulnerability Globe)&lt;br /&gt;
|powerup&lt;br /&gt;
|Sound played when an Invulnerability Globe is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsgetpow.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|ashard (Armor Shard)&lt;br /&gt;
|powerup&lt;br /&gt;
|Sound played when an Armor Shard is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsgetpow.wav&lt;br /&gt;
|-&lt;br /&gt;
|bpack (Berserk Pack)&lt;br /&gt;
|powerup&lt;br /&gt;
|Sound played when a Berserk Pack is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsgetpow.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|map (Computer Map)&lt;br /&gt;
|powerup&lt;br /&gt;
|Sound played when a Computer Map is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsgetpow.wav&lt;br /&gt;
|-&lt;br /&gt;
|backpack&lt;br /&gt;
|powerup&lt;br /&gt;
|Sound played when a Backpack! is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsgetpow.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|smed (Small Med-Pack)&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a Small Med-Pack is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|use&lt;br /&gt;
|Sound played when a Small Med-Pack is used.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsgetpow.wav&lt;br /&gt;
|-&lt;br /&gt;
|lmed (Large Med-Pack)&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a Large Med-Pack is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|use&lt;br /&gt;
|Sound played when a Large Med-Pack is used.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsgetpow.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|phase (Phase Device)&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a Phase Device is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-&lt;br /&gt;
|hphase (Homing Phase Device)&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a Homing Phase Device is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|epack (Environmental Pack)&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when an Enviromental Pack is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-&lt;br /&gt;
|nuke (Thermonuclear Bomb)&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a Thermonuclear Bomb is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|explode&lt;br /&gt;
|Sound played when a Thermonuclear Bomb detonates.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsfirxpl.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|mod_power&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a Power Mod Pack is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-&lt;br /&gt;
|mod_agility&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when an Agility Mod Pack is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|mod_bulk&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a Bulk Mod Pack is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-&lt;br /&gt;
|mod_tech&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a Technical Mod Pack is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|garmor (Green Armor)&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when Green Armor is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-&lt;br /&gt;
|barmor (Blue Armor)&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when Blue Armor is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|rarmor (Red Armor)&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when Red Armor is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-&lt;br /&gt;
|sboots (Steel Boots)&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when Steel Boots are picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|pboots (Protective Boots)&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when Protective Boots are picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-&lt;br /&gt;
|psboots (Plasteel Boots)&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when Plasteel Boots are picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|ammo (10mm Ammo)&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when 10mm ammo is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-&lt;br /&gt;
|shell (Shotgun Shell)&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when Shotgun Shells are picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|rocket&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when Rockets are picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-&lt;br /&gt;
|cell (Power Cell)&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when Power Cells are picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|knife&lt;br /&gt;
|attack&lt;br /&gt;
|Sound played when attacking with a Combat Knife.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspunch.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a Combat Knife is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-&lt;br /&gt;
|pistol&lt;br /&gt;
|fire&lt;br /&gt;
|Sound played when a pistol is fired.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspistol.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a pistol is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|reload&lt;br /&gt;
|Sound played when reloading a pistol.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|shotgun&lt;br /&gt;
|fire&lt;br /&gt;
|Sound played when a shotgun is fired.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsshotgn.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a shotgun is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|reload&lt;br /&gt;
|Sound played when reloading a shotgun.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-&lt;br /&gt;
|ashotgun (Combat Shotgun)&lt;br /&gt;
|fire&lt;br /&gt;
|Sound played when a combat shotgun is fired.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsshotgn.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a combat shotgun is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|reload&lt;br /&gt;
|Sound played when reloading a combat shotgun.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|pump&lt;br /&gt;
|Sound played when pumping a shell into the combat shotgun.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dssgcock.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|dshotgun (Double Shotgun)&lt;br /&gt;
|fire&lt;br /&gt;
|Sound played when a double shotgun is fired.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsdshtgn.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a double shotgun is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|reload&lt;br /&gt;
|Sound played when reloading a double shotgun.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-&lt;br /&gt;
|chaingun&lt;br /&gt;
|fire&lt;br /&gt;
|Sound played when a chaingun is fired. The sound plays for each shot.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspistol.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a chaingun is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|reload&lt;br /&gt;
|Sound played when reloading a chaingun.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|plasma (Plasma Rifle)&lt;br /&gt;
|fire&lt;br /&gt;
|Sound played when a plasma rifle is fired. The sound plays for each shot.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsplasma.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a plasma rifle is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|reload&lt;br /&gt;
|Sound played when reloading a plasma rifle.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-&lt;br /&gt;
|bazooka (Rocket Launcher)&lt;br /&gt;
|fire&lt;br /&gt;
|Sound played when a rocket launcher is fired.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dslaunc.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a rocket launcher is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|reload&lt;br /&gt;
|Sound played when reloading a rocket launcher.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|explode&lt;br /&gt;
|Sound played when the fired rocket explodes.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsrxplod.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|chainsaw&lt;br /&gt;
|attack&lt;br /&gt;
|Sound played when attacking with a chainsaw.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dssawhit.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a chainsaw is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-&lt;br /&gt;
|bfg9000&lt;br /&gt;
|fire&lt;br /&gt;
|Sound played when a BFG 9000 is fired.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbfg.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when a BFG 9000 is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|reload&lt;br /&gt;
|Sound played when reloading a BFG 9000.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|explode&lt;br /&gt;
|Sound played when the BFG shot hits something.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsrxplod.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|spear (Longinus Spear)&lt;br /&gt;
|attack&lt;br /&gt;
|Sound played when attacking with the Longinus Spear.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsgetpow.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|pickup&lt;br /&gt;
|Sound played when the Longinus Spear is picked up.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|explode&lt;br /&gt;
|Sound played for the explosions when using the spear's alt-fire.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsrxplod.wav&lt;br /&gt;
|-&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|Default sound for melee actions.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsclaw.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|reload&lt;br /&gt;
|&lt;br /&gt;
|Default sound for reloading.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dswpnup.wav&lt;br /&gt;
|-&lt;br /&gt;
|pickup&lt;br /&gt;
|&lt;br /&gt;
|Default sound for picking up items.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsitemup.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|fire&lt;br /&gt;
|&lt;br /&gt;
|Default sound for firing a weapon.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsfirsht.wav&lt;br /&gt;
|-&lt;br /&gt;
|explode&lt;br /&gt;
|&lt;br /&gt;
|Default sound for explosions.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsfirxpl.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|powerup&lt;br /&gt;
|&lt;br /&gt;
|Default sound for picking up powerups.&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsgetpow.wav&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Being Action Descriptions ==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; align=&amp;quot;left&amp;quot; cell-padding=&amp;quot;1ex&amp;quot; | Action&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; align=&amp;quot;left&amp;quot; cell-padding=&amp;quot;1ex&amp;quot; | Description&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|die&lt;br /&gt;
|The sound that plays when this type of being dies.&lt;br /&gt;
|-&lt;br /&gt;
|act&lt;br /&gt;
|The sound that plays randomly whenever this type of being does something.&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|hit&lt;br /&gt;
|The sound that plays when this type of being is hurt.  For the player, this plays when the player walks over acid or lava.&lt;br /&gt;
|-&lt;br /&gt;
|melee&lt;br /&gt;
|The sound that plays when this type of being performs a melee attack.  For the player, this is for an empty handed fist attack.&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|hoof&lt;br /&gt;
|The sound that plays each time the being moves.  This sound is typically only used for boss enemies.&lt;br /&gt;
|-&lt;br /&gt;
|phase&lt;br /&gt;
|The sound that plays when this type of being uses a phase device or homing phase device.&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|fire&lt;br /&gt;
|The sound that plays when this type of being uses their natural ranged weapon.&lt;br /&gt;
|-&lt;br /&gt;
|explode&lt;br /&gt;
|The sound that plays when this type of being's natural ranged attack hits something and has an explosion radius (even if it's only 1).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Being Default Sounds ==&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; align=&amp;quot;left&amp;quot; cell-padding=&amp;quot;1ex&amp;quot; | Being&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; align=&amp;quot;left&amp;quot; cell-padding=&amp;quot;1ex&amp;quot; | Action&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; align=&amp;quot;left&amp;quot; cell-padding=&amp;quot;1ex&amp;quot; | Default Sound (LQ)&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; align=&amp;quot;left&amp;quot; cell-padding=&amp;quot;1ex&amp;quot; | Default Sound (HQ)&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|solider (Player)&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspldeth.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsplpain.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspunch.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|phase&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dstelept.wav&lt;br /&gt;
|-&lt;br /&gt;
|former (Former Human)&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspodth1.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsposact.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspopain.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspunch.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|sergeant (Former Sergeant)&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspodth2.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsposact.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspopain.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspunch.wav&lt;br /&gt;
|-&lt;br /&gt;
|captain (Former Captain)&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspodth2.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsposact.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspopain.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspunch.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|commando (Former Commando)&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspodth3.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsposact.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspopain.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspunch.wav&lt;br /&gt;
|-&lt;br /&gt;
|imp&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbgdth1.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbgact.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspopain.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsclaw.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|fire&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsfirsht.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|explode&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsfirxpl.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|lostsoul&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsfirxpl.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dssklatk.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsdmpain.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dssklatk.wav&lt;br /&gt;
|-&lt;br /&gt;
|pain (Pain Elemental)&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspedth.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspesit.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspepain.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsclaw.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|demon&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dssgtdth.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsdmact.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsdmpain.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dssgtatk.wav&lt;br /&gt;
|-&lt;br /&gt;
|cacodemon&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dscacdth.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dscacsit.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsdmpain.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsclaw.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|fire&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsfirsht.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|explode&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsfirxpl.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|arachno (Arachnotron)&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbspdth.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbspact.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsdmpain.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsclaw.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|fire&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsplasma.wav&lt;br /&gt;
|-&lt;br /&gt;
|knight (Hell Knight)&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dskntdth.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dskntsit.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsdmpain.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsclaw.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|fire&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsfirsht.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|explode&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsfirxpl.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|baron&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbrsdth.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbrssit.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsdmpain.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsclaw.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|fire&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsfirsht.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|explode&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsfirxpl.wav&lt;br /&gt;
|-&lt;br /&gt;
|mancubus&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsmandth.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsmansit.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsmnpain.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|fire&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsfirsht.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|explode&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsfirxpl.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|revenant&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsskedth.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsskesit.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspopain.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsskepch.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|fire&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsskeatk.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|explode&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbarexp.wav&lt;br /&gt;
|-&lt;br /&gt;
|arch (Arch-Vile)&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsvildth.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsvilact.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsvipain.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|fire&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsvilatk.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|bruiser&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbrsdth.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbrssit.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsdmpain.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsclaw.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|fire&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsfirsht.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|explode&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsfirxpl.wav&lt;br /&gt;
|-&lt;br /&gt;
|cyberdemon&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dscybdth.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dscybsit.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsdmpain.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|hoof&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dshoof.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|jc&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspodth1.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsposact.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspopain.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dspunch.wav&lt;br /&gt;
|-&lt;br /&gt;
|angel (Angel of Death)&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbrsdth.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbrssit.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsbrssit.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsclaw.wav&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|hoof&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dshoof.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|mastermind&lt;br /&gt;
|die&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsspidth.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|act&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsdmact.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|hit&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsdmpain.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|melee&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsclaw.wav&lt;br /&gt;
|-style=&amp;quot;background:#333&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|hoof&lt;br /&gt;
|&lt;br /&gt;
|wavhq/dsmetal.wav&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Strategy:Shotgun</id>
		<title>Strategy:Shotgun</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Strategy:Shotgun"/>
				<updated>2025-08-11T12:34:43Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''This article is about strategy for the [[shotgun]] itself as a [[weapons|weapon]], not the category of [[weapons]] colloquially known as [[Shotgun_Types|&amp;quot;shotguns&amp;quot;]]. For specific strategies for the individual [[weapons]], please see the associated entries under their [[Shotgun_Types|names]]. For [[Shotgun_Types|&amp;quot;shotguns&amp;quot;]] in general, please see [[Strategy:Shotgun_Types|Strategy:Shotgun Types]].''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{infostrat switch}}&lt;br /&gt;
== '''Overview''' ==&lt;br /&gt;
=== '''Brief Summary''' ===&lt;br /&gt;
The [[shotgun]] is one of the first [[weapons]] that you can find in DRL, and it will help you survive the first few levels. Even without the appropriate build, it is still incredibly versatile for the beginning of the game; with the appropriate build, even further.&lt;br /&gt;
&lt;br /&gt;
Aside from greatly out-damaging a [[pistol]] in close to mid-range, [[shotgun_shell|shotgun shells]] will definitely be plentiful for a while. Probably the most widely employed [[shotgun]] strategy is [[Strategy:Corner-shooting|&amp;quot;corner-shooting&amp;quot;]], which is literally aiming the [[shotgun]] around a corner that you're standing at, and hitting enemies on the other side. For a more in-depth explanation, please see [[Strategy:Corner-shooting]] (''TBA'').&lt;br /&gt;
&lt;br /&gt;
The [[shotgun]] is also the first weapon you can get that is immediately capable of causing [[knock-back]]. When enough damage is dealt to an enemy in one shot (''anyone who is aware of the exact number required, please edit this entry accordingly''), and it survives, it will be pushed back a square. This can be used to give yourself breathing room, or even to kill an enemy by pushing them into [[Fluids|acid]] or [[Fluids|lava]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Examination''' ==&lt;br /&gt;
=== '''Advantages to using the shotgun''' ===&lt;br /&gt;
* Easy to find&lt;br /&gt;
* Tons of ammo early on&lt;br /&gt;
* Strong corner-shooting game&lt;br /&gt;
* Knock back capable&lt;br /&gt;
* Ammo used amongst nearly all shotguns; can move on to a different shotgun and keep your ammo&lt;br /&gt;
* [[Traits#Shottyman|Shottyman]], [[Traits#Shottyhead|Shottyhead]] and [[Traits#Army_of_the_Dead|Army of the Dead]] trait selections&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== '''Disadvantages to using the shotgun''' ===&lt;br /&gt;
* Drops off in effectiveness mid to late game&lt;br /&gt;
* Only holds one shell at a time; must be reloaded prior to firing each time&lt;br /&gt;
* Slow reload speed&lt;br /&gt;
* Poor base choice for an [[Assemblies|Assembly]] ([[Shotgun_Types|other types of shotgun]] serve this role better)&lt;br /&gt;
* Ineffective at extreme distances&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remember that [[shotgun_shell|shotgun shells]] fired from a regular, unmodified [[shotgun]] are considered [[Damage_type#shrapnel|Shrapnel]] for the purposes of [[Damage_type|damage type]] and [[resistance|resistances]].&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Shotgun_Types</id>
		<title>Shotgun Types</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Shotgun_Types"/>
				<updated>2025-08-11T12:34:36Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
&lt;br /&gt;
''The following is a list of [[weapons]] that are [[Weapon_Families|classified]] as the &amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[http://doom.chaosforge.org/wiki/Shotgun_Types shotgun type]&amp;lt;/span&amp;gt; for the purposes of [[Challenges]] and [[Traits]].''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Types ==&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== '''Standard''' ===&lt;br /&gt;
*[[Shotgun]]&lt;br /&gt;
*[[Combat_shotgun|Combat shotgun]]&lt;br /&gt;
*[[Double_shotgun|Double shotgun]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== '''[[Assemblies|Assembly]]''' ===&lt;br /&gt;
*{{assembly link|Elephant gun}}&lt;br /&gt;
*{{assembly link|Tactical shotgun}}&lt;br /&gt;
*{{assembly link|Focused double shotgun}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*{{SpAssembly link|Plasmatic shrapnel shotgun}}&lt;br /&gt;
*{{SpAssembly link|Plasmatic shrapnel combat shotgun}}&lt;br /&gt;
*{{SpAssembly link|Plasmatic shrapnel double shotgun}}&lt;br /&gt;
*{{SpAssembly link|Plasmatic shrapnel assault shotgun}}&lt;br /&gt;
*{{SpAssembly link|Plasmatic shrapnel plasma shotgun}}&lt;br /&gt;
*{{SpAssembly link|Plasmatic shrapnel super shotgun}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*{{SpAssembly link|Nano-shrapnel shotgun}}&lt;br /&gt;
*{{SpAssembly link|Nano-shrapnel combat shotgun}}&lt;br /&gt;
*{{SpAssembly link|Nano-shrapnel double shotgun}}&lt;br /&gt;
*{{SpAssembly link|Nano-shrapnel assault shotgun}}&lt;br /&gt;
*{{SpAssembly link|Nano-shrapnel plasma shotgun}}&lt;br /&gt;
*{{SpAssembly link|Nano-shrapnel super shotgun}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== '''Special''' ===&lt;br /&gt;
* {{exotic link|Assault shotgun}}&lt;br /&gt;
* {{exotic link|Plasma shotgun}}&lt;br /&gt;
* {{exotic link|Super shotgun}}&lt;br /&gt;
* {{unique link|Jackhammer}}&lt;br /&gt;
* {{unique link|Frag Shotgun}}&lt;br /&gt;
&lt;br /&gt;
== '''About Shotguns''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== '''Overview and Strategy''' ===&lt;br /&gt;
{{infostrat switch}}&lt;br /&gt;
The weapons from the shotgun family of DRL all have an cone-shaped area of effect attack that makes them unique and powerful. Shotguns never miss any target in their affected area, and they always do at least one damage to each target. The size of the shotgun blast varies from weapon to weapon. It is governed by two parameters: range and spread. The range of a shotgun determines how far the blast extends from the attacker, and the spread determines the half-width of the blast when it reaches it's furthest point.&lt;br /&gt;
&lt;br /&gt;
Shotgun damage also diminishes over distance. Each shotgun has a reduction rating that determines what percentage of damage is taken off per tile of [[distance]]. This penalty is applied linearly, and it is applied even at point-blank range. Rounding is to the nearest integer (0.5 rounds to even).&lt;br /&gt;
&lt;br /&gt;
DRL uses shotguns with four different Area of Effect types:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;rules: cols; border: 2px solid darkred; border-spacing: 0; font-size: 90%; margin: 0.25em 0.5em;&amp;quot;&lt;br /&gt;
|colspan=11 style=&amp;quot;background: darkred; color: yellow; font-size: 120%; text-align: center&amp;quot;|'''Shotgun Area of Effect  Types'''&lt;br /&gt;
|- &lt;br /&gt;
|style=&amp;quot;text-align: center; padding: 1ex; border: solid darkred; border-width: 0 1px 1px 0&amp;quot; width=100|'''Name'''&lt;br /&gt;
|style=&amp;quot;text-align: center; padding: 1ex; border: solid darkred; border-width: 0 1px 1px 1px&amp;quot; width=50|'''Range'''&lt;br /&gt;
|style=&amp;quot;text-align: center; padding: 1ex; border: solid darkred; border-width: 0 1px 1px 1px&amp;quot; width=50|'''Spread'''&lt;br /&gt;
|style=&amp;quot;text-align: center; padding: 1ex; border: solid darkred; border-width: 0 0 1px 1px&amp;quot; width=50|'''Reduction'''&lt;br /&gt;
|- style=&amp;quot;background: #333;&amp;quot;&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 1px 1px 0 0&amp;quot;|normal&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 1px 1px 0 1px&amp;quot;|15&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 1px 1px 0 1px&amp;quot;|3&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 1px 0 0 1px&amp;quot;|7%&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 1px 1px 0 0&amp;quot;|focused&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 1px 1px 0 1px&amp;quot;|15&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 1px 1px 0 1px&amp;quot;|2&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 1px 0 0 1px&amp;quot;|5%&lt;br /&gt;
|- style=&amp;quot;background: #333;&amp;quot;&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 1px 1px 0 0&amp;quot;|wide&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 1px 1px 0 1px&amp;quot;|8&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 1px 1px 0 1px&amp;quot;|3&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 1px 0 0 1px&amp;quot;|10%&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align: left; padding-right: 1ex; border: solid darkred; border-width: 1px 1px 0 0&amp;quot;|plasma&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 1px 1px 0 1px&amp;quot;|15&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 1px 1px 0 1px&amp;quot;|3&lt;br /&gt;
|style=&amp;quot;text-align: center; border: solid darkred; border-width: 1px 0 0 1px&amp;quot;|5%&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== '''Area of Effect Details''' ===&lt;br /&gt;
{{Technical}}&lt;br /&gt;
To calculate a shotgun's area of effect, first a target square is calculated by extrapolating from the vector pointing at the manually targeted square. The true target will be a tile that is at the shotgun's maximum range with an approximately parallel vector. Then, for each tile in a (2 &amp;amp;times; spread + 1) side-length square around the target, the game traces out the path of a missile until it hits a wall. (Shotgun blasts go through enemies.) The missile paths are truncated if the distance along one of the axes becomes greater than the shotgun's range. For each tile that was traced out in at least one of the missile paths, damage is applied.&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Weapon_Families</id>
		<title>Weapon Families</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Weapon_Families"/>
				<updated>2025-08-11T12:34:29Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
''The following is a list of the various classifications of [[weapons]] that exist within DRL. To see all the weapons that belong to a particular &amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[http://drl.chaosforge.org/wiki/Weapon_Families family]&amp;lt;/span&amp;gt;, click on the appropriate link below.''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*[[Melee_Types|Melee Types]]&lt;br /&gt;
*[[Pistol_Types|Pistol Types]]&lt;br /&gt;
*[[Shotgun_Types|Shotgun Types]]&lt;br /&gt;
*[[Rapid-fire_Types|Rapid-fire Types]]&lt;br /&gt;
*[[Explosive_Types|Explosive Types]]&lt;br /&gt;
*[[Big__Gun_Types|Big Gun Types]]&lt;br /&gt;
*[[Misc_Types|Miscellaneous Types]]&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Strategy:Cyberdemon</id>
		<title>Strategy:Cyberdemon</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Strategy:Cyberdemon"/>
				<updated>2025-08-11T12:34:21Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
&lt;br /&gt;
==Basic Strategy==&lt;br /&gt;
&lt;br /&gt;
The Cyberdemon is a particularly bulky boss who will greet you at the end of Deimos (Deimos 8: The Tower of Babel) and occasionally in the final levels of Ao100. He packs a melee attack that does 1d3 + 15 damage and a ranged rocket attack that does 6d6 damage. He is unique from most other DRL enemies in two ways—first, he knows where you are and he will get into range and attack unwaveringly. Second, he has a longer sight range than you do (unless you have MCe). Indeed, his large sight range makes it difficult to outspeed him, even though he only has 110% speed.&lt;br /&gt;
&lt;br /&gt;
There are three basic strategies often employed to take down the Cyberdemon.&lt;br /&gt;
&lt;br /&gt;
*Gather a large amount of [[dodge]]. Two levels in Hellrunner and donning [[Tactical armor]] is an example of having high dodge. This will ensure that most of the Cyberdemon's attacks will miss if the player dodges correctly. An even more surefire way to handle him using this method is to take the Dodgemaster trait. This will guarantee that his rockets will never score a direct hit. Be careful, though; the level is a bit cramped, considering the pillars. It is easy to get hit by the splash from the explosion. Also note that he will slowly close to melee range over the course of his attacks. You may need to retreat if you're in danger of being melee'd. This method is advised for low-DPS builds that rely on speed (i.e., MSh).&lt;br /&gt;
&lt;br /&gt;
*Build a high-DPS character. Some characters do so much damage that they can kill the Cyberdemon before he is able to fire more than 4 or 5 rockets. Even if you get hit by 2 or 3 of them, that damage is easily mitigated by armor and medkits. An example of a typical high-DPS build might be a focus on rapid-fire, with traits such as SoB and TH. Dual pistols often fall into this category as well. Outside of weapon-restricted builds, rocket launchers and BFGs perform well against him. Remember to time your shots so that you can still get a dodge off before he fires! Fire speed helps a lot here.&lt;br /&gt;
&lt;br /&gt;
*Melee him. The Cyberdemon doesn't do as much damage in melee as getting hit directly by a rocket. Even a non-melee build is able to make good use of the guaranteed chainsaw (from [[The Chained Court]]) to attack him, provided an armor with high melee resistance and/or armor value has been found. A red armor is doable with a melee build; for a non-melee build, it is advised to have something a little beefier.&lt;br /&gt;
&lt;br /&gt;
==Tips==&lt;br /&gt;
&lt;br /&gt;
*Use the pillars to buffer yourself when you first enter the level. You won't know exactly where the Cyberdemon is, so stay on the stairs-side of a pillar and wait for him to fire a rocket at you. The resulting chunk blown out of the pillar will allow you to pinpoint his location, so you can get into the fire-&amp;gt;dodge-&amp;gt;fire groove without giving him a free hit.&lt;br /&gt;
&lt;br /&gt;
*The Cyberdemon is immune to acid and lava pools, so don't bother using the Acid Spitter or Napalm Launcher against him.&lt;br /&gt;
&lt;br /&gt;
*Although the Cyberdemon is immune to knockback in The Tower of Babel, he can be knocked back in Ao100.&lt;br /&gt;
&lt;br /&gt;
*The Cyberdemon will fire a rocket and some [[time]] (1.0s?) will pass before he reloads his rocket launcher. A message will be displayed to let the player know when the Cyberdemon has reloaded. This marks roughly the halfway point to when he will fire again. Take it as your cue to dodge. Check your firing speed (with the @ key) to get a rough idea of how many times you can attack before you need to dodge.&lt;br /&gt;
&lt;br /&gt;
*When you reach Deimos 7, try to clear the level without using the powerups. If you're lucky, you will get an invincibility or berserk near the stairs, which will make the fight trivial. (You remembered to take the chainsaw with you, right?)&lt;br /&gt;
&lt;br /&gt;
*The Cyberdemon will fire at you as long as you're in what would be his sight range; even if you're behind a pillar. This means that a character with sufficiently high movement speed can fire off some shots, duck behind a pillar to block the attack, then pop back out and fire off some more shots. Don't count on the pillar to take more than 3 or 4 hits for you, though.&lt;br /&gt;
&lt;br /&gt;
[[User:Ashannar|Ashannar]] 11:34, 23 March 2013 (CET)&lt;br /&gt;
:&amp;quot;''Although the Cyberdemon is immune to knockback in The Tower of Babel, he can be knocked back in Ao100.''&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:I do not know if this was true in prior versions, but I can confirm this is not true as of 0.9.9.7, Cyberdemons in that version are still very much immune to knockback regardless of where they're encountered. [[User:Omega Tyrant|Omega Tyrant]] ([[User talk:Omega Tyrant|talk]]) 02:37, 6 August 2023 (UTC)&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Modding:Color_(0.9.9.7)</id>
		<title>Modding:Color (0.9.9.7)</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Modding:Color_(0.9.9.7)"/>
				<updated>2025-08-11T12:34:09Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In console mode all game tiles are associated with a particular color. Choosing a good color scheme is an important part of modding, but the choice is limited--only 16 colors exist in the standard [http://en.wikipedia.org/wiki/VGA-compatible_text_mode VGA compatible console] which, when combined into foreground and background, results in only 256 possible combinations. There are some special engine colors as well to further complicate matters.&lt;br /&gt;
&lt;br /&gt;
In graphics mode all game tiles are associated with a particular sprite.  The sprites obviously support more than 16 colors. They can also be further manipulated by engine effects, color overlays (both additive and subtractive), and outlines.&lt;br /&gt;
&lt;br /&gt;
==Console Colors ==&lt;br /&gt;
=== Color Definitions ===&lt;br /&gt;
{{Template:Color}}&lt;br /&gt;
&lt;br /&gt;
=== Special Colors ===&lt;br /&gt;
{{Template:Special_Color}}&lt;br /&gt;
&lt;br /&gt;
=== Background Colors ===&lt;br /&gt;
DRL uses 4 bit color. In 4 bit color consoles the lower four bits correspond to the foreground color while the upper four bits correspond to the background color (usually). When you assign a color using the color constants above the upper bits will equal zero, which is the default background color--black. You can change this by explicitly assigning the upper 4 bits a value using code similar to the following:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;color = LIGHTGRAY + (RED * 16)&amp;lt;/source&amp;gt;&lt;br /&gt;
The above statement will display &amp;lt;span style=&amp;quot;color:silver; background:maroon&amp;quot;&amp;gt;light gray text over a red background&amp;lt;/span&amp;gt;. Officially this is unsupported. Unofficially it is used often enough that support for it will most likely continue. There is a caveat though--some combinations are used by the [[#Special Colors|special colors]] above and thus cannot be used for regular items.&lt;br /&gt;
&lt;br /&gt;
=== Notes and Advice ===&lt;br /&gt;
* The [[Manual:color.lua|color.lua]] script can be used by players to customize tiles.&lt;br /&gt;
** Many objects have a color_id property that can be used to prevent unscrupulous players from distinguishing between items such as levers by color.&lt;br /&gt;
* Console colors are not always consistent. Brown in particular can vary a lot and more closely mimics orange in some environments.&lt;br /&gt;
* Dark Blue is hard to see on a black background and should be used sparingly, especially with beings who can be frustrating when hard to see.&lt;br /&gt;
* Background colors should be used sparingly, if at all. The clear divides break immersion.&lt;br /&gt;
* Be aware of common roguelike coloring customs, especially those used by NetHack and (obviously) DRL.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Color Sets ==&lt;br /&gt;
A color set in DRL is an array in the form of '''{ ''red'', ''green'', ''blue'', ''alpha'' }'''.  Each value is a decimal between 0.0 and 1.0, though at present ''alpha'' is not used.&lt;br /&gt;
&lt;br /&gt;
=== Coscolor ===&lt;br /&gt;
A coscolor is an '''additive''' modifier found on [[Modding:cell|cells]], [[Modding:being|beings]], [[Modding:item|items]], and [[Modding:missile|missiles]]. To have any effect a sprite must have a grayscale color map associated with it.  Currently only a small number of sprites, such as mod packs, do.&lt;br /&gt;
&lt;br /&gt;
=== Overlay ===&lt;br /&gt;
An overlay is a '''subtractive''' modifier found on [[Modding:being|beings]] and [[Modding:item|items]]. It will remove colors from sprites--the overlay '''{ ''1.0'', ''0.0'', ''0.0'', ''1.0'' }''' for instance would turn a sprite completely red.  This option is mostly intended for creating placeholder sprites quickly and is rather limited.  Status effects react to overlays in unusual ways and since adding color or changing hues is impossible it is difficult to get a good end result.&lt;br /&gt;
&lt;br /&gt;
=== Glow ===&lt;br /&gt;
A glow is an '''additive''' modifier found on [[Modding:being|beings]] and [[Modding:item|items]].  Unlike the other graphical modifiers this directly adds a color to a sprite based on its outline (minus its shadow).  The effect is a smooth and pleasant glow effect which can be used to great effect without worrying about side effects.&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Modding:level_object_(0.9.9.7)</id>
		<title>Modding:level object (0.9.9.7)</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Modding:level_object_(0.9.9.7)"/>
				<updated>2025-08-11T12:33:48Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The ''level'' object in DRL pulls triple duty: it stores and publishes properties relevant to the current level, it provides access to the [[Modding:level API|level API]] which includes procedures from Lua, DRL, and valkyrie, and through clever use of metatables it exposes the light, cell type, and HP arrays stored in the valkyrie ''LuaMapNode'' object.  Here we focus on its representation as an object.&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
{{drltable|Properties |3|{{Table3Col&lt;br /&gt;
  |es=background: #333;&lt;br /&gt;
  |c1=font-family:monospace; text-align:right; vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |c2=padding:0px 2px;&lt;br /&gt;
  |c3=padding:0px 2px;&lt;br /&gt;
  |status              |{{modarg|word}}    |This is for use by level designers and is preserved after a level is exited.&lt;br /&gt;
  |data                |{{modarg|anything}}|This is for use by level designers.&lt;br /&gt;
  |name                |{{modarg|string}}  |This is the level name as displayed on the HUD.&lt;br /&gt;
  |name_number         |{{modarg|word}}    |This controls the &amp;quot;LevX&amp;quot; part of the level name. If zero, it won't be displayed.&lt;br /&gt;
  |danger_level        |{{modarg|word}}    |Level generation parameter that usually corresponds to depth.&lt;br /&gt;
  |style               |{{modarg|byte}}    |The style (tile set) used by the level generation functions.&lt;br /&gt;
  |&amp;lt;u&amp;gt;id&amp;lt;/u&amp;gt;           |{{modarg|string}}  |The id of the current level&lt;br /&gt;
  |&amp;lt;u&amp;gt;special_exit&amp;lt;/u&amp;gt; |{{modarg|string}}  |The id of the level that red stairs lead to&lt;br /&gt;
  |}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
level.data and level.status are used to store information during (in the case of data) and after (in the case of status) level execution.  Although one can work around the need for either it is considered good practice to use these two fields.  level.status is limited; it can only store a single word value and it is intended for storing the current state of a level--just entered, reached the halfway mark, finished, etc.  It is preserved so you may use this information to influence future levels.  level.data is meant to track the current level as it exists now, should a word value be insufficient.  Careful use of level.data and chaining/[[Modding:level blueprint#level_onenteritem|OnEnter]] hooks can also modify level behaviour in special modes (such as challenge modes) while keeping the level itself ignorant of the concept of a challenge.&lt;br /&gt;
&lt;br /&gt;
== Array Properties ==&lt;br /&gt;
{{drltable|Array Properties|3|{{Table3Col&lt;br /&gt;
  |es=background: #333;&lt;br /&gt;
  |c1=font-family:monospace; text-align:right; vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |c2=padding:0px 2px;&lt;br /&gt;
  |c3=padding:0px 2px;&lt;br /&gt;
  |flags[{{modarg|Level Flag}}]|{{modarg|boolean}}|Get or set level flags&lt;br /&gt;
  |light[{{modarg|coord}}][{{modarg|Light Flag}}]|{{modarg|boolean}}|Get or set cell light flags*&lt;br /&gt;
  |map[{{modarg|coord}}]|{{modarg|cell}}|Get or set cells on a map by cell id&lt;br /&gt;
  |hp[{{modarg|coord}}]|{{modarg|byte}}|Get or set cell HP values&lt;br /&gt;
  |}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
* As a special extension you can pass an area to level.light when setting flags and the procedure will automatically iterate through every coord&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Modding:generator_API</id>
		<title>Modding:generator API</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Modding:generator_API"/>
				<updated>2025-08-11T12:33:46Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''This page is currently under construction.''&lt;br /&gt;
&lt;br /&gt;
The generator holds all of the ever-present functions used to create the random maps in DRL. It also contains a variety of helper functions, many of them useful if not vital to the creation of intricate and meticulous game design.&lt;br /&gt;
&lt;br /&gt;
== API ==&lt;br /&gt;
&lt;br /&gt;
Please note that the type &amp;quot;integer&amp;quot; indicates an numeric value without a decimal part.  It does not indicate the range of acceptable values.&lt;br /&gt;
&lt;br /&gt;
The argument type &amp;quot;CellID&amp;quot; may be the numeric or string ID of a cell.&lt;br /&gt;
&lt;br /&gt;
The argument type &amp;quot;CellSet&amp;quot; may be the numeric ID, string ID, or a list of numeric and/or string IDs.&lt;br /&gt;
&lt;br /&gt;
The argument type &amp;quot;Flags&amp;quot; expects a list of [[Modding:Constants|flag constants]] of the indicated type.  &lt;br /&gt;
&lt;br /&gt;
An argument name in [square brackets] is an optional one.  The function description will indicate how the function operates if it is omitted.&lt;br /&gt;
&lt;br /&gt;
=== Generator API Function List ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;border: 2px solid darkred; border-spacing: 0; font-size: 90%; margin: 0.25em 0.5em;&amp;quot;&lt;br /&gt;
 ! colspan=&amp;quot;2&amp;quot; style=&amp;quot;background: darkred; color: yellow; font-size: 120%; text-align: center&amp;quot;|'''Generator Interface - Functions'''&lt;br /&gt;
 {{Table2Col&lt;br /&gt;
  |es=background: #333; &lt;br /&gt;
  |c1=font-weight:bold; text-align:right; vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |c2=padding:0px 2px;&lt;br /&gt;
  ||'''[[#Basic Cell Handling Functions|Basic Cell Handling Functions]]'''&lt;br /&gt;
  |{{modarg|integer}}|{{moddef|list|get_cell|dot||Coord|loc}}&lt;br /&gt;
  |{{modarg|string}}|{{moddef|list|get_cell_id|dot||Coord|loc}}&lt;br /&gt;
  |{{modarg|integer}}|{{moddef|list|fast_get_cell|dot||integer|x|integer|y}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|set_cell|dot||Coord|loc|CellID|what}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|fast_set_cell|dot||integer|x|integer|y|integer|what}}&lt;br /&gt;
  ||'''[[#Map Checking Functions|Map Checking Functions]]'''&lt;br /&gt;
  |{{modarg|integer}}|{{moddef|list|around|dot||Coord|where|CellSet|what}}&lt;br /&gt;
  |{{modarg|integer}}|{{moddef|list|cross_around|dot||Coord|where|CellSet|what}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|is_empty|dot||Coord|where|Flags|reqs}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|is_empty_area|dot||Area|where|Flags|reqs}}  &lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|scan|dot||Area|where|CellID|good}}&lt;br /&gt;
  ||'''[[#Map Searching Functions|Map Searching Functions]]'''&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|drop_coord|dot||Coord|where|Flags|reqs}}&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|find_coord|dot||CellSet|what|Area|[where]}}&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|random_coord|dot||Area|[where]}}&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|find_random_coord|dot||CellSet|what|Area|[where]}}&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|find_empty_coord|dot||CellSet|what|Flags|reqs|Area|[where]}}&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|random_empty_coord|dot||Flags|reqs|Area|[where]}}&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|find_random_empty_coord|dot||CellSet|what|Flags|reqs|Area|[where]}}&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|safe_empty_coord|dot||Area|[where]}}&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|standard_empty_coord|dot}}&lt;br /&gt;
  ||'''[[#Advanced Cell Handling Functions|Advanced Cell Handling Functions]]'''&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|fill|dot||CellID|what|Area|[where]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|fill_pattern|dot||Area|where|boolean|horiz|Table|line1|Table|[line2]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|fill_edges|dot||CellID|what}}&lt;br /&gt;
  |{{modarg|Table}}|{{moddef|list|each|dot||CellID|what|Area|[where]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|set_blood|dot||Area|[where]|boolean|[value]|CellID|[what]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|set_permanence|dot||Area|[where]|boolean|[value]|CellID|[what]}}&lt;br /&gt;
  |{{modarg|Table}}|{{moddef|list|cell_set|dot||CellSet|cells}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|restore_walls|dot||CellID|wallCell|boolean|keepFluids}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|plot_line|dot||Coord|where|boolean|horiz|CellID|cell|CellSet|block}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|plot_lines|dot||Coord|where|Area|larea|boolean|horiz|CellID|cell|CellSet|block}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|scatter|dot||Area|where|CellID|good|CellID|fill|integer|count}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|scatter_blood|dot||Area|where|CellID|[good]|integer|count}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|scatter_put|dot||Area|where|Table|translation|string|tile|CellID|good|integer|count}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|transmute|dot||CellID|to|CellSet|from|Area|[where]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|transmute_marker|dot||Flag|marker|CellID|To|Area|[where]}}&lt;br /&gt;
  ||'''[[#Tile Handling Functions|Tile Handling Functions]]'''&lt;br /&gt;
  |{{modarg|Table}}|{{moddef|list|create_translation|dot||Table|code}}&lt;br /&gt;
  |{{modarg|Tile}}|{{moddef|list|tile_new|dot||string|map|Table|translation}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|tile_place|dot||Coord|where|Tile|what}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|place_tile|dot||Table|translation|string|tile|integer|x|integer|y}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|place_dungen_tile|dot||Table|code|Tile|tile|Coord|where}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|place_symmetry_quad|dot||string|tile|Table|translation}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|place_proto_map|dot||Coord|where|string|proto_map|string|proto_key|Table|code}}&lt;br /&gt;
  ||'''[[#Room Handling Functions|Room Handling Functions]]'''&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|add_room|dot||Area|room|string|[class]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|add_rooms|dot}}&lt;br /&gt;
  |{{modarg|Room}}|{{moddef|list|get_room|dot||integer|min_size|integer|max_x|integer|max_y|integer|max_area|string|[class]}}&lt;br /&gt;
  |{{modarg|integer, integer}}|{{moddef|list|get_endpoints|dot||Coord|where|boolean|horiz|CellSet|what}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|handle_rooms|dot||integer|count|boolean|no_monsters}}&lt;br /&gt;
  ||'''[[#Generation Algorithm Functions|Generation Algorithm Functions]]'''&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|run_drunkard_walk|dot||Area|where|Coord|start|integer|steps|CellID|fill|CellSet|[ignore]|boolean|[stop_at_edge]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|drunkard_walks|dot||integer|amount|integer|steps|CellID|fill|CellSet|[ignore]|boolean|[stop_at_edge]|Area|[where]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|contd_drunkard_walks|dot||integer|amount|integer|steps|CellID|fill|CellSet|edges1|CellSet|edges2|CellSet|[ignore]|boolean|[stop_at_edge]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|warehouse_fill|dot||CellSet|fill|Area|where|integer|size|integer|count|integer|special_chance|CellSet|special}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|place_blob|dot||Coord|start|integer|size|CellID|cell}}&lt;br /&gt;
  ||'''[[#Generator Helper Functions|Generator Helper Functions]]'''&lt;br /&gt;
  |{{modarg|&amp;lt;value&amp;gt;, &amp;lt;value&amp;gt;}}|{{moddef|list|roll_pair|dot||Table|list}}&lt;br /&gt;
  |{{modarg|integer}}|{{moddef|list|being_weight|dot}}&lt;br /&gt;
  |{{modarg|integer}}|{{moddef|list|item_amount|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|horiz_river|dot||CellID|cell|integer|width|boolean|[bridge]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|vert_river|dot||CellID|cell|integer|width|boolean|bridge|integer|position}}&lt;br /&gt;
{{moddef|list|vert_river|dot||CellID|cell|integer|width|boolean|bridge|Coord|position}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_rivers|dot||boolean|allow_horiz|boolean|allow_more}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_fluids|dot||Area|[where]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_barrels|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_stairs|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_special_stairs|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|place_player|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|run|dot||Generator|gen}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|reset|dot}}&lt;br /&gt;
  ||'''[[#Dungeon Generation Functions|Dungeon Generation Functions]]'''&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_tiled|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|maze_dungeon|dot||CellID|floor|CellID|wall|integer|granularity|integer|tries|integer|min_size|integer|max_size}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_caves_dungeon|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_caves_2_dungeon|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_lava_dungeon|dot}}&lt;br /&gt;
  ||'''[[#Event Handler Functions|Event Handler Functions]]'''&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|roll_event|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|setup_flood_event|dot||integer|direction|integer|step|CellID|cell}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|setup_deadly_air_event|dot||integer|step}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|setup_explosion_event|dot||integer|step|integer|size|integer|dice|integer|[content]}}&lt;br /&gt;
{{moddef|list|setup_explosion_event|dot||integer|step|Table|size|integer|dice|integer|[content]}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|setup_targeted_event|dot||integer|step}}&lt;br /&gt;
  |}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Basic Cell Handling Functions ===&lt;br /&gt;
;{{moddef|desc|get_cell|dot|integer|Coord|loc}}&lt;br /&gt;
Gets the Numeric ID (NID) of the [[Modding:Cell|cell]] at a given map position.&lt;br /&gt;
:''loc'': The coordinates of the cell to get.&lt;br /&gt;
:'''Returns''': The NID of the cell.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|get_cell_id|dot|string|Coord|loc}}&lt;br /&gt;
Gets the ID of the [[Modding:Cell|cell]] at a given map position.&lt;br /&gt;
:''loc'': The coordinates of the cell to get.&lt;br /&gt;
:'''Returns''': The string ID of the cell.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|fast_get_cell|dot|integer|integer|x|integer|y}}&lt;br /&gt;
Gets the Numeric ID (NID) of the [[Modding:Cell|cell]] at a given map position.&lt;br /&gt;
:''x'': The X position of the cell to get.&lt;br /&gt;
:''y'': The Y position of the cell to get.&lt;br /&gt;
:'''Returns''': The NID of the cell.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|set_cell|dot||Coord|loc|CellID|what}}&lt;br /&gt;
Assigns a [[Modding:Cell|cell]] to a map position.&lt;br /&gt;
:''loc'': The coordinates of the position to set.&lt;br /&gt;
:''what'': The ID of the cell to assign to the position.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|fast_set_cell|dot||integer|x|integer|y|integer|what}}&lt;br /&gt;
Assigns a [[Modding:Cell|cell]] to a map position.&lt;br /&gt;
:''x'': The X position of the cell to set.&lt;br /&gt;
:''y'': The Y position of the cell to set.&lt;br /&gt;
:''what'': The NID (string IDs not allowed) of the cell to assign to the position.&lt;br /&gt;
----&lt;br /&gt;
=== Map Checking Functions ===&lt;br /&gt;
;{{moddef|desc|around|dot|integer|Coord|where|CellSet|what}}&lt;br /&gt;
Checks the positions adjacent to a location (including diagonally adjacent) and returns the number of cells that match one of the indicated cell IDs.&lt;br /&gt;
:''where'': The coordinate to check around.  The coordinate sent in this way is not checked, only adjacent cells are.&lt;br /&gt;
:''what'': The cell(s) to check for.&lt;br /&gt;
:'''Returns''': The number of cells (from 0 to 8) that matched one of the ''what'' cell IDs.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|cross_around|dot|integer|Coord|where|CellSet|what}}&lt;br /&gt;
Checks the positions adjacent to a location (but not diagonally adjacent) and returns the number of cells that match one of the indicated cell IDs.&lt;br /&gt;
:''where'': The coordinates to check around.  The coordinate sent in this way is not checked, only adjacent cells are.&lt;br /&gt;
:''what'': The cell(s) to check for.&lt;br /&gt;
:'''Returns''': The number of cells (from 0 to 4) that matched one of the ''what'' cell IDs.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|is_empty|dot|boolean|Coord|where|Flags|reqs}}&lt;br /&gt;
Checks to see if the indicated cell is &amp;quot;empty&amp;quot;, defining &amp;quot;empty&amp;quot; based on a list of criteria.&lt;br /&gt;
:''where'': The position to check.&lt;br /&gt;
:''reqs'': A list of EmptyFlags (named numeric constants that start with EF_) indicating which types of objects or properties the position cannot have.  For example, if the flag EF_NOBEINGS is sent, the function only returns true if the map position does not contain a [[Modding:Being|being]].  See [[Modding:Constants#Empty_Flags]] for more information.&lt;br /&gt;
:'''Returns''': ''True'' if the cell satisfies all of the conditions indicated in ''reqs'', ''False'' otherwise.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|is_empty_area|dot|boolean|Area|where|Flags|reqs}}&lt;br /&gt;
Checks to see if the indicated area is &amp;quot;empty&amp;quot;, defining &amp;quot;empty&amp;quot; based on a list of criteria.&lt;br /&gt;
:''where'': The area to check.&lt;br /&gt;
:''reqs'': A list of EmptyFlags (named numeric constants that start with EF_) indicating which types of objects or properties the area cannot have.  For example, if the flag EF_NOBEINGS is sent, the function only returns true if the area does not contain a [[Modding:Being|being]].  See [[Modding:Constants#Empty_Flags]] for more information.&lt;br /&gt;
:'''Returns''': ''True'' if every cell in the area satisfies all of the conditions indicated in ''reqs'', ''False'' otherwise.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|scan|dot|boolean|Area|where|CellID|good}}&lt;br /&gt;
Checks to see if the entire area is filled with a certain cell.&lt;br /&gt;
:''where'': The area to check.&lt;br /&gt;
:''good'': The cell to look for.&lt;br /&gt;
:'''Returns''': ''True'' if all cells in the area are ''good'', ''False'' otherwise.&lt;br /&gt;
----&lt;br /&gt;
=== Map Searching Functions ===&lt;br /&gt;
;{{moddef|desc|drop_coord|dot|Coord|Coord|where|Flags|reqs}}&lt;br /&gt;
Finds the nearest &amp;quot;empty&amp;quot; coordinate to a given coordinate, defining &amp;quot;empty&amp;quot; based on a list of criteria.&lt;br /&gt;
:''where'': The coordinate to try.  If this coordinate is &amp;quot;empty&amp;quot;, this coordinate will be returned.&lt;br /&gt;
:''reqs'': A list of EmptyFlags (named numeric constants that start with EF_) indicating which types of objects or properties the coordinate cannot have.  For example, if the flag EF_NOBEINGS is sent, the function only returns a coordinate that does not contain a [[Modding:Being|being]].  See [[Modding:Constants#Empty_Flags]] for more information.&lt;br /&gt;
:'''Returns''': The nearest coordinate the satisfies the criteria.  If the supplied coordinate meets the criteria, that coordinate will be returned.  If not a nearby, random, coordinate will be checked. &lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|find_coord|dot|Coord|CellSet|what|Area|[where]}}&lt;br /&gt;
Searches the map for the first coordinate containing one of the indicated cell IDs.&lt;br /&gt;
:''what'': The cell(s) to search for.&lt;br /&gt;
:''where'': ''Optional.'' The area to restrict the search to.  If omitted, the coordinate can be picked from anywhere on the map.&lt;br /&gt;
:'''Returns''': The coordinates of the first position that contains one of the ''what'' cell IDs.  The map is checked row by row starting from the top, going from left to right across each row.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|random_coord|dot|Coord|Area|[where]}}&lt;br /&gt;
Searches for a random coordinate within the specified area.&lt;br /&gt;
:''where'': ''Optional.'' The area to restrict the coordinate to.  If omitted, the coordinate can be picked from anywhere on the map.&lt;br /&gt;
:'''Returns''': A random coordinate.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|find_random_coord|dot|Coord|CellSet|what|Area|[where]}}&lt;br /&gt;
Searches for a random coordinate within the specified area that contains one of the specified cell IDs.&lt;br /&gt;
:''what'': The cell(s) to search for.&lt;br /&gt;
:''where'' : ''Optional.'' The area to restrict the search to.  If omitted, the coordinate can be picked from anywhere on the map.&lt;br /&gt;
:'''Returns''': A random coordinate that meets the supplied criteria.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|find_empty_coord|dot|Coord|CellSet|what|Flags|reqs|Area|[where]}}&lt;br /&gt;
Searches the map for the first &amp;quot;empty&amp;quot; coordinate containing one of the indicated cell IDs, defining &amp;quot;empty&amp;quot; based on a list of criteria.&lt;br /&gt;
:''what'': The cell(s) to search for.&lt;br /&gt;
:''reqs'':  A list of EmptyFlags (named numeric constants that start with EF_) indicating which types of objects or properties the coordinate cannot have.  For example, if the flag EF_NOBEINGS is sent, the function only returns a coordinate that does not contain a [[Modding:Being|being]].  See [[Modding:Constants#Empty_Flags]] for more information.&lt;br /&gt;
:''where'': ''Optional.'' The area to restrict the search to.  If omitted, the coordinate can be picked from anywhere on the map.&lt;br /&gt;
:'''Returns''': The coordinates of the first position that meets the supplied criteria.  The map is checked row by row starting from the top, going from left to right across each row.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|random_empty_coord|dot|Coord|Flags|reqs|Area|[where]}}&lt;br /&gt;
Searches the map for a random coordinate that is &amp;quot;empty&amp;quot;, defining &amp;quot;empty&amp;quot; based on a list of criteria.&lt;br /&gt;
:''reqs'': A list of EmptyFlags (named numeric constants that start with EF_) indicating which types of objects or properties the random coordinate cannot have.  For example, if the flag EF_NOBEINGS is sent, the function only returns a coordinate that does not contain a [[Modding:Being|being]].  See [[Modding:Constants#Empty_Flags]] for more information.&lt;br /&gt;
:''where'': ''Optional.'' The area to restrict the search to.  If omitted, the coordinate can be picked from anywhere on the map.&lt;br /&gt;
:'''Returns''': A random coordinate that meets the supplied criteria.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|find_random_empty_coord|dot|Coord|CellSet|what|Flags|reqs|Area|[where]}}&lt;br /&gt;
Searches the map for a random &amp;quot;empty&amp;quot; coordinate containing one of the indicated cell IDs, defining &amp;quot;empty&amp;quot; based on a list of criteria.&lt;br /&gt;
:''what'': The cell(s) to search for.&lt;br /&gt;
:''reqs'':  A list of EmptyFlags (named numeric constants that start with EF_) indicating which types of objects or properties the random coordinate cannot have.  For example, if the flag EF_NOBEINGS is sent, the function only returns a coordinate that does not contain a [[Modding:Being|being]].  See [[Modding:Constants#Empty_Flags]] for more information.&lt;br /&gt;
:''where'': ''Optional.'' The area to restrict the search to.  If omitted, the coordinate can be picked from anywhere on the map.&lt;br /&gt;
:'''Returns''': A random coordinate that meets the supplied criteria.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|random_square|dot|Coord|CellSet|what}}&lt;br /&gt;
Searches for a random 3x3 area containing only specified cells.&lt;br /&gt;
:''what'': The cell(s) to search for.&lt;br /&gt;
:'''Returns''': The center coordinate of the random 3x3 area.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|safe_empty_coord|dot|Coord|Area|[where]}}&lt;br /&gt;
Searches for a random coordinate that meets certain predetermined criteria.&lt;br /&gt;
&lt;br /&gt;
The function will try to find a coordinate that does not contain a being, item, staircase, wall, harmful terrain, spawning restrictions (cells marked with LF_NOSPAWN), and is more than 5 spaces from the player (EF_NOBEINGS, EF_NOITEMS, EF_NOSTAIRS, EF_NOBLOCK, EF_NOHARM, EF_NOSPAWN, and EF_NOSAFE).  If a valid space isn't found, the function will ignore distance from the player (EF_NOSAFE).  If a valid space still can't be found, the function will ignore stairs and harmful terrain (EF_NOSTAIRS and EF_NOHARM).&lt;br /&gt;
:''where'': ''Optional.'' The area to restrict the initial pass to.  If a valid coordinate is not found within the area after ignoring stairs and harmful terrain, the search is restarted and expanded automatically to the entire map.  If omitted, the entire map will be searched.&lt;br /&gt;
:'''Returns''': A random coordinate that meets the criteria.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|standard_empty_coord|dot|Coord}}&lt;br /&gt;
Searches for a random coordinate that meets certain predetermined criteria.&lt;br /&gt;
&lt;br /&gt;
The function will search for a coordinate that does not contain a being, item, staircase, wall, harmful terrain, or spawning restrictions (EF_NOBEINGS, EF_NOITEMS, EF_NOSTAIRS, EF_NOBLOCK, EF_NOHARM, and EF_NOSPAWN).&lt;br /&gt;
:'''Returns''': A random coordinate that meets the criteria.&lt;br /&gt;
----&lt;br /&gt;
=== Advanced Cell Handling Functions ===&lt;br /&gt;
;{{moddef|desc|fill|dot||CellID|what|Area|[where]}}&lt;br /&gt;
Fills an area of the map with a given cell.&lt;br /&gt;
:''what'': The cell to fill with.&lt;br /&gt;
:''where'': ''Optional.'' The area to fill with the cell.  If omitted, the entire map will be filled.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|fill_pattern|dot||Area|where|boolean|horiz|string|Table|line1|Table|[line2]}}&lt;br /&gt;
Fills an area of the map with a pattern of cells.&lt;br /&gt;
:''where'': The area to fill.&lt;br /&gt;
:''horiz'': If ''True'', the pattern will fill each row left to right, then move to the next row down in the area.  If ''False'', the pattern will fill each column top to bottom, then move to the next column right in the area. &lt;br /&gt;
:''line1'': The pattern to fill with.  If the pattern is shorter than the area size, the pattern will loop.  The pattern does not restart at the end of a row or column.&lt;br /&gt;
:''line2'': ''Optional.'' If given, each time the end of row (if ''horiz'' is ''True'') or column (if ''horiz'' is ''False'') is reached, the function will switch to filling with the other pattern.  That is, the first row will use ''line1'' then the second will use ''line2'', then the third will use ''line1'' again, etc.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|fill_edges|dot||CellID|what}}&lt;br /&gt;
Fills the edges of the map with the given cell.&lt;br /&gt;
:''what'': The cell to fill with.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|each|dot|Table|CellID|what|Area|[where]}}&lt;br /&gt;
Searches for a cell and returns a table containing every location it was found.&lt;br /&gt;
:''what'': The cell to search for.&lt;br /&gt;
:''where'': ''Optional.'' The area to restrict the search to.&lt;br /&gt;
:'''Returns''': A table containing a list of [[Modding:Coord|Coord]] objects.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|set_blood|dot||Area|[where]|boolean|[value]|CellID|[what]}}&lt;br /&gt;
Adds blood to the map or removes blood from it.&lt;br /&gt;
:''where'': ''Optional.'' The area to affect.  If omitted, the entire map will selected.&lt;br /&gt;
:''value'': ''Optional.'' ''True'' adds blood.  ''False'' removes it.  If omitted, the default is to add blood.&lt;br /&gt;
:''what'': ''Optional.'' If provided, only locations containing the given cell are affected.  If omitted, all cells in the area are affected.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|set_permanence|dot||Area|[where]|boolean|[value]|CellID|[what]}}&lt;br /&gt;
Makes cell permanent or removes their permanence.&lt;br /&gt;
:''where'': ''Optional.'' The area to affect.  If omitted, the entire map will be selected.&lt;br /&gt;
:''value'': ''Optional.'' ''True'' adds permanence.  ''False'' removes it.  If omitted, the default is to add permanence.&lt;br /&gt;
:''what'': ''Optional.'' If provided, only locations containing the given cell are affected.  If omitted, wall cells (which includes crate cells) are affected.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|cell_set|dot|Table|CellSet|cells}}&lt;br /&gt;
Creates a cell group.&lt;br /&gt;
:''cells'': A list of cells to add to the group.&lt;br /&gt;
:'''Returns''': A cell group table.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|restore_walls|dot||CellID|wallCell|boolean|keepFluids}}&lt;br /&gt;
Fixes the edge walls of the map.&lt;br /&gt;
:''wallCell'': The cell to fill the edge of the map with.&lt;br /&gt;
:''keepFluids'': ''True'' to maintain any fluid tiles on the edge of the map.  ''False'' to overwrite them.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|plot_line|dot||Coord|where|boolean|horiz|CellID|cell|CellSet|block}}&lt;br /&gt;
Splits an area into two at the indicated location.&lt;br /&gt;
:''where'': The starting point.&lt;br /&gt;
:''horiz'': ''True'' draws along the indicated X position of the ''where'' coordinate.  ''False'' draws along the indicated Y position of the ''where'' coordinate.&lt;br /&gt;
:''cell'': The cell that will be used to split the area.&lt;br /&gt;
:''block'': The cell(s) that block the line plotting.  The drawn line will stop before hitting a coordinate with one of these cells.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|plot_lines|dot||Coord|where|Area|larea|boolean|horiz|CellID|cell|CellSet|block}}&lt;br /&gt;
Splits an area into two at the indicated location.&lt;br /&gt;
:''where'': The starting point.&lt;br /&gt;
:''larea'': The boundaries of the line.  The line will not extend past the edge of the area.&lt;br /&gt;
:''horiz'': ''True'' draws along the indicated X position of the ''where'' coordinate.  ''False'' draws along the indicated Y position of the ''where'' coordinate.&lt;br /&gt;
:''cell'': The cell that will be used to split the area.&lt;br /&gt;
:''block'': The cell(s) that block the line plotting.  The drawn line will stop before hitting a coordinate with one of these cells.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|scatter|dot||Area|where|CellID|good|CellID|fill|integer|count}}&lt;br /&gt;
Randomly places a certain cell around the map.&lt;br /&gt;
:''where'': The area to scatter the cell in.&lt;br /&gt;
:''good'': Only this locations with this cell will be changed by the function.&lt;br /&gt;
:''fill'': The cell to scatter around the area.&lt;br /&gt;
:''count'': The number to attempt to place.  If the chosen location is not ''good'', then it will not change it.  The final number placed may be less than ''count'' (or even 0), but never more.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|scatter_blood|dot||Area|where|CellID|[good]|integer|count}}&lt;br /&gt;
Randomly adds blood in an area.&lt;br /&gt;
:''where'': The area to scatter blood in.&lt;br /&gt;
:''good'': ''Optional.'' If defined, only locations with this cell will have blood added.  If omitted, any location my have blood added.&lt;br /&gt;
:''count'': The number of attempts.  On each attempt, a random cell in the area will be chosen to have blood added.  The number of cell that will end up bloody may be less than ''count'' (or even 0), but never more.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|scatter_put|dot||Area|where|Table|translation|string|tile|CellID|good|integer|count}}&lt;br /&gt;
Randomly adds a specified tile (a defined arrangement of cells) around the map.&lt;br /&gt;
:''where'': The area to scatter the tile in.  The tiles will only be placed in locations entirely within the area.&lt;br /&gt;
:''translation'': A table with to be used with the ''tile'' argument.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:''tile'': A multi-line string, one row of the tile per line, that lays out the arrangment of the cells.  Refer to this (will be linked soon) for more information&lt;br /&gt;
:''good'': Only locations with this cell will be valid for the tile placement.  If any coordinates of the selected placement area are not ''good'', the tile will not be placed at that location.&lt;br /&gt;
:''count'': The number of tiles to try to place.  The placement will continue until this many have been placed, or 10,000 attempts have been made, whichever comes first.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|transmute|dot||CellID|to|CellSet|from|Area|[where]}}&lt;br /&gt;
Changes all of one cell on the map to another cell.&lt;br /&gt;
:''to'': The cell that will replace the existing cells.&lt;br /&gt;
:''from'': The cell(s) that will be replaced.&lt;br /&gt;
:''where'': ''Optional.'' If specified, only cells in the area are changed.  If omitted, the function will change cells across the entire map.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|transmute_marker|dot||Flag|marker|CellID|To|Area|[where]}}&lt;br /&gt;
Changes all positions on the map that have a specified LightFlag (a named constant starting with &amp;quot;LF&amp;quot;, no underscore) to another cell.&lt;br /&gt;
:''marker'': The LightFlag to check for.  Only cells with this flag will be changed.&lt;br /&gt;
:''to'': The cell that will replace the existing cells.&lt;br /&gt;
:''where'': ''Optional.'' If specified, only cells in the area are changed.  If omitted, the function will change cells across the entire map.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Tile Handling Functions ===&lt;br /&gt;
;{{moddef|desc|create_translation|dot|Table|Table|code}}&lt;br /&gt;
Parses a translation table.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:''code'': The translation table.&lt;br /&gt;
:'''Returns''': A parsed translation table.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|tile_new|dot|Tile|string|map|Table|translation}}&lt;br /&gt;
Creates a new tile object.&lt;br /&gt;
:''map'': A multi-line string containing the arrangement of the tile using the ''translation'' to convert the characters to cells.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:''translation'': A table with to be used with the ''map'' argument.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:'''Returns''': The new tile object.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|tile_place|dot||Coord|where|Tile|what}}&lt;br /&gt;
Places the cells of the tile on the map.&lt;br /&gt;
:''where'': The coordinate that the upper-left of the tile should reside at.&lt;br /&gt;
:''what'': The tile object that will be placed.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|place_tile|dot||Table|translation|string|tile|integer|x|integer|y}}&lt;br /&gt;
Combines the tile_new and tile_place functions together, by placing a tile using a string and translation table.&lt;br /&gt;
:''translation'': A table with to be used with the ''tile'' argument.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:''tile'': A multi-line string containing the arrangement of the tile using the ''translation'' to convert the characters to cells.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:''x'': The X position that the tile will be placed at.&lt;br /&gt;
:''y'': The Y position that the tile will be placed at.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|place_dungen_tile|dot||Table|code|Tile|tile|Coord|where}}&lt;br /&gt;
Places an entire tile, including beings and items in the translation, on the map.&lt;br /&gt;
:''code'': The translation table.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:''tile'': A multi-line string containing the arrangement of the tile using the ''translation'' to convert the characters to cells and indicate the positions of the beings and items.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:''where'': The coordinate the tile will be placed at.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|place_symmetry_quad|dot||string|tile|Table|translation}}&lt;br /&gt;
Takes a tile object and places it in all four corners.  The tile object should be setup for the upper left corner and will be mirrored to the other corners.  The tiles are placed one space from the map edge.&lt;br /&gt;
:''tile'': A multi-line string containing the arrangement of the tile using the ''translation'' to convert the characters to cells and indicate the positions of the beings and items.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
:''translation'': The translation table.  Refer to this (will be linked soon) for more information.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|place_proto_map|dot||Coord|where|string|proto_map|string|proto_key|Table|code}}&lt;br /&gt;
Creates a map using multiple tile sets.&lt;br /&gt;
:''where'': The upper-left position of the map where the tiles will be layout from.&lt;br /&gt;
:''proto_map'': A string indicating the arrangement of the different pieces of the map.  e.g., &amp;quot;ABCD&amp;quot;, will lay out 4 different tiles with A on the far left and D on the far right.&lt;br /&gt;
:''proto_key'': A table containing, for each character in ''proto_map'', a table of the possible tiles for that section.&lt;br /&gt;
:''code'': The translation table for all the tile possibilities.  Refer to this (will be linked soon) for more information.  All tiles use the same translation table.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Room Handling Functions ===&lt;br /&gt;
;{{moddef|desc|add_room|dot||Area|room|string|[class]}}&lt;br /&gt;
Marks an area that can become a special room.&lt;br /&gt;
:''room'': The area of the room.  This includes the walls.&lt;br /&gt;
:''class'': ''Optional.'' A string used to denote which room generators can be used on this room.  If omitted, the class used is &amp;quot;closed&amp;quot;.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|add_rooms|dot}}&lt;br /&gt;
Finds all the areas that can be rooms on a map and adds them to the appropriate meta-map tables.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|get_room|dot|Room|integer|min_size|integer|max_x|integer|max_y|integer|max_area|string|class}}&lt;br /&gt;
Selects a room given certain criteria.&lt;br /&gt;
:''min_size'': The smallest X and Y dimensions the room can be.&lt;br /&gt;
:''max_x'': The maximum width of the room.&lt;br /&gt;
:''max_y'': The maximum height of the room.&lt;br /&gt;
:''max_area'': The largest area the room can be.&lt;br /&gt;
:''class'': ''Optional.'' The string denoting which room classes are valid for this room generator.  If omitted, &amp;quot;any&amp;quot; is used, which does not restrict the selection of rooms.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|get_endpoints|dot|integer, integer|Coord|where|boolean|horiz|CellSet|what}}&lt;br /&gt;
Finds the ends of a line of cells.&lt;br /&gt;
:''where'': The starting coordinate.&lt;br /&gt;
:''horiz'': ''True'' checks horizontally.  ''False'' checks vertically.&lt;br /&gt;
:''what'': The cell(s) that make up the line to check.  The functions stops at the first cell '''not''' in this list.&lt;br /&gt;
:'''Returns''': Two integers.  If ''horiz'' is ''True'', these are the X positions the line stops at.  If ''horiz'' is ''False'', these are the Y positions the line stops at.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|handle_rooms|dot||integer|count|boolean|no_monsters}}&lt;br /&gt;
Runs the rooms selection and setup process for a map.&lt;br /&gt;
:''count'': The number of rooms to attempt to place.&lt;br /&gt;
:''no_monsters'': ''True'' will exclude room generators that place monsters.  ''False'' will not.&lt;br /&gt;
----&lt;br /&gt;
=== Generation Algorithm Functions ===&lt;br /&gt;
;{{moddef|desc|run_drunkard_walk|dot||Area|where|Coord|start|integer|steps|CellID|fill|CellSet|[ignore]|boolean|[stop_at_edge]|Area|where}}&lt;br /&gt;
Runs an algorithm that walks to random adjacent spaces.&lt;br /&gt;
:''where'': The area that the algorithm will run in.  If the algorithm tries to leave the area, it will stop early or will be pushed back in the area (''stop_at_edge'' will determine which of these happen).&lt;br /&gt;
:''start'': The location the algorithm will begin at.&lt;br /&gt;
:''steps'': The number of steps the algorithm will take.  The number of spaces covered by the algorithm will be at most this number.&lt;br /&gt;
:''fill'': The cell that will be placed at each location the algorithm hits.&lt;br /&gt;
:''ignore'': ''Optional.'' If specified, the algorithm will not place the ''fill'' cell in any location that has one of the cell(s) specified.  If omitted, no locations are ignored.&lt;br /&gt;
:''stop_at_edge'': ''Optional.'' If ''True'', the algorithm will end early if it moves past the end of the area.  If ''False'', the algorithm will clamp to the area (any moves to outside the area get moved back in the area).  If omitted, the default is to clamp.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|drunkard_walks|dot||integer|amount|integer|steps|CellID|fill|CellSet|[ignore]|boolean|[stop_at_edge]|Area|[where]}}&lt;br /&gt;
Runs multiple &amp;quot;drunken walk&amp;quot; algorithms.&lt;br /&gt;
:''amount'': The number of times to perform the algorithm.&lt;br /&gt;
:''steps'': The number of steps each run of the algorithm will take.  The number of spaces covered by the algorithm will be at most the ''amount'' times the number of ''steps''.&lt;br /&gt;
:''fill'': The cell that will be placed at each location the algorithm hits.&lt;br /&gt;
:''ignore'': ''Optional.'' If specified, the algorithm will not place the ''fill'' cell in any location that has one of the cell(s) specified.  If omitted, no locations are ignored.&lt;br /&gt;
:''stop_at_edge'': ''Optional.'' If ''True'', the algorithm will end early if it moves past the end of the area.  If ''False'', the algorithm will clamp to the area (any moves to outside the area get moved back in the area).  If omitted, the default is to clamp.&lt;br /&gt;
:''where'': ''Optional.'' The area the algorithm will run in.  If the algorithm tries to leave the area, it will stop early or will be pushed back in the area (''stop_at_edge'' will determine which of these happen).  If omitted, the default is entire area minus the very edge.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|contd_drunkard_walks|dot||integer|amount|integer|steps|CellID|fill|CellSet|edges1|CellSet|edges2|CellSet|[ignore]|boolean|[stop_at_edge]}}&lt;br /&gt;
Runs multiple &amp;quot;drunken walk&amp;quot; algorithms starting at a space that doesn't have certain cells around it.&lt;br /&gt;
:''amount'': The number of times to perform the algorithm.&lt;br /&gt;
:''steps'': The number of steps each run of the algorithm will take.  The number of spaces covered by the algorithm will be at most the ''amount'' times the number of ''steps''.&lt;br /&gt;
:''fill'': The cell that will be placed at each location the algorithm hits.&lt;br /&gt;
:''edges1'': The algorithm will not start on a space with a cell listed here next to it.&lt;br /&gt;
:''edges2'': The algorithm will not start on a space with a cell listed here next to it.&lt;br /&gt;
:''ignore'': ''Optional.'' If specified, the algorithm will not place the ''fill'' cell in any location that has one of the cell(s) specified.  If omitted, no locations are ignored.&lt;br /&gt;
:''stop_at_edge'': ''Optional.'' If ''True'', the algorithm will end early if it moves past the end of the area.  If ''False'', the algorithm will clamp to the area (any moves to outside the area get moved back in the area).  If omitted, the default is to clamp.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|warehouse_fill|dot||CellID|fill|Area|where|integer|[size]|integer|[count]|integer|[special_chance]|CellID|[special]}}&lt;br /&gt;
Fills an area with random squares of cells.&lt;br /&gt;
:''fill'': The cell(s) to use for each square.  If a list is given, one is chosen at random for each square.&lt;br /&gt;
:''where'': The area to fill.&lt;br /&gt;
:''size'': ''Optional.'' The size of the squares to use. If omitted, the default is 2.&lt;br /&gt;
:''count'': ''Optional.'' The number of attempts. If omitted, the default is 50.&lt;br /&gt;
:''special_chance'': ''Optional.'' A number indicating the probability of using a special list of cells to fill the square with instead of the ''fill'' list.  The roll used for the chance is based on the ''size'' parameter.  A number from 1 to (100 * ''size'') is chosen for each square and if the roll is less than the special_chance number, the ''special'' cell set is used to fill the square instead. If omitted, all squares will be filled from the ''fill'' set.&lt;br /&gt;
:''special'': ''Optional.'' The list of cells to use if the special set is to be used, based on ''special_chance''. If omitted, all squares will be filled from the ''fill'' set.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|place_blob|dot||Coord|start|integer|size|CellID|cell}}&lt;br /&gt;
Fills an area by expanding to random edge coordinates.&lt;br /&gt;
:''start'': The position to start the blob at.&lt;br /&gt;
:''size'': The number of spaces to expand the blob to.&lt;br /&gt;
:''cell'': The cell to fill the blob area with.&lt;br /&gt;
----&lt;br /&gt;
=== Generator Helper Functions ===&lt;br /&gt;
;{{moddef|desc|roll_pair|dot|&amp;lt;value&amp;gt;, &amp;lt;value&amp;gt;|Table|list}}&lt;br /&gt;
Takes a list of values of any type and returns two different values randomly from the list.&lt;br /&gt;
:''list'': The list to choose from.&lt;br /&gt;
:'''Returns''': Two different values.  If the list only contains one choice, it will be returned, but only once.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|being_weight|dot}}&lt;br /&gt;
Gets the total danger level for the current dungeon level.&lt;br /&gt;
'''Returns''': The danger level for the current dungeon level.  This value is calcuated using the current difficulty and ''level.danger_level''.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|item_amount|dot}}&lt;br /&gt;
Gets the number of items to drop for the current dungeon level.&lt;br /&gt;
'''Returns''': The number of items to drop for the current dungeon level.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|horiz_river|dot||CellID|cell|integer|width|boolean|[bridge]}}&lt;br /&gt;
Places a horizontal river on the map.&lt;br /&gt;
:''cell'': The cell to use for the river.  It does not have to be a fluid cell.&lt;br /&gt;
:''width'': The width of the river.&lt;br /&gt;
:''bridge'': ''Optional.'' If ''True'', a 2 space wide bridge will be placed at a random coordinate on the river.  If ''False'', no bridge will be placed.  If omitted, the default is to not place a bridge.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|vert_river|dot||CellID|cell|integer|width|boolean|bridge|integer|[position]}}&lt;br /&gt;
;{{moddef|desc|vert_river|dot||CellID|cell|integer|width|boolean|bridge|Coord|[position]}}&lt;br /&gt;
Places a vertical river on the map.&lt;br /&gt;
:''cell'': The cell to use for the river.  It does not have to be a fluid cell.&lt;br /&gt;
:''width'': The width of the river.&lt;br /&gt;
:''bridge'': ''Optional.'' If ''True'', a 2 space wide bridge will be placed at a random coordinate on the river.  If ''False'', no bridge will be placed.  If omitted, the default is to not place a bridge.&lt;br /&gt;
:: NOTE: Because of a bug, a bridge will always be placed on the river, even if this value is set to ''False'' or omitted.&lt;br /&gt;
:''position'':  A coordinate or an integer.  If an integer is supplied, this is the X position of the river's left edge.  If a coordinate is supplied, the river will start at this coordinate.  If omitted, the river's left edge will be selected from between X = 19 to 58.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_rivers|dot||boolean|allow_horiz|boolean|allow_more}}&lt;br /&gt;
Creates rivers based on normal DRL river generation.&lt;br /&gt;
:''allow_horiz'': ''True'' allows horizontal rivers to be generated.  ''False'' will prevent the generation of horizontal rivers.&lt;br /&gt;
:''allow_more'': ''True'' allows multiple vertical rivers.  ''False'' will prevent more than one vertical river from being placed.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_fluids|dot||Area|[where]}}&lt;br /&gt;
Creates fluids based on normal DRL fluid generation.&lt;br /&gt;
:''where'': ''Optional.'' The area to generate fluids in.  If omitted, the area used will be the entire map minus the very edge.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_barrels|dot}}&lt;br /&gt;
Creates barrels based on normal DRL barrel generation.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_stairs|dot}}&lt;br /&gt;
Creates the normal staircase based on normal DRL stair generation.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_special_stairs|dot}}&lt;br /&gt;
Creates the special staircase based on normal DRL special stair generation.  Whether a special staircase is placed depends on the level.special_exit value.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|place_player|dot}}&lt;br /&gt;
Places the player on a random empty space.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|run|dot||Generator|gen}}&lt;br /&gt;
Runs a generator object.  These are stored in the generators table.&lt;br /&gt;
:''gen'': The generator object to run.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|reset|dot}}&lt;br /&gt;
Resets the map.&lt;br /&gt;
----&lt;br /&gt;
=== Dungeon Generation Functions ===&lt;br /&gt;
;{{moddef|desc|generate_tiled|dot}}&lt;br /&gt;
Creates a tiled dungeon, also known as a &amp;quot;normal&amp;quot; dungeon.  This only creates the layout, it does not place beings, items, stairs, barrels, or the player.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|maze_dungeon|dot||CellID|floor|CellID|wall|integer|granularity|integer|tries|integer|min_size|integer|max_size}}&lt;br /&gt;
Creates a maze dungeon.  This only creates the layout, it does not place beings, items, stairs, barrels, or the player.&lt;br /&gt;
:''floor'': The cell to use for the floor of the maze.&lt;br /&gt;
:''wall'': The cell to use for the wall of the maze.&lt;br /&gt;
:''granularity'': This denotes the size of the maze's paths.&lt;br /&gt;
:''tries'': Number of attempts to place a new wall in the maze.&lt;br /&gt;
:''min_size'': The smallest possible size of a wall.&lt;br /&gt;
:''max_size'': The largest possible size of a wall.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_caves_dungeon|dot}}&lt;br /&gt;
Runs the generation script for the cave dungeon.  This is an all inclusive function, it also places all beings and items.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_caves_2_dungeon|dot}}&lt;br /&gt;
Runs the generation script for the cave-city dungeon.  This is an all inclusive function, it also places all beings and items.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_lava_dungeon|dot}}&lt;br /&gt;
Runs the generation script for the lava dungeon.  This is an all inclusive function, it also places all beings and items.&lt;br /&gt;
----&lt;br /&gt;
=== Event Handler Functions ===&lt;br /&gt;
;{{moddef|desc|roll_event|dot}}&lt;br /&gt;
Picks an event from the events table and sets it up.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|setup_flood_event|dot||integer|direction|integer|step|CellID|cell}}&lt;br /&gt;
Runs the setup script for the flood event.&lt;br /&gt;
:''direction'': Use 1 to flood from the left.  Use -1 to flood from the right.&lt;br /&gt;
:''step'': Number of turns (0.1 second intervals) between each flood step.&lt;br /&gt;
:''cell'': The cell to flood with.  This does not have to be a fluid cell.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|setup_deadly_air_event|dot||integer|step}}&lt;br /&gt;
Runs the setup script for the deadly air event.&lt;br /&gt;
:''step'': Number of turns between each &amp;quot;chill&amp;quot; (loss of HP).&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|setup_explosion_event|dot||integer|step|integer|size|integer|dice|integer|[content]}}&lt;br /&gt;
;{{moddef|desc|setup_explosion_event|dot||integer|step|Table|size|integer|dice|integer|[content]}}&lt;br /&gt;
Runs the setup script for the explosion event.&lt;br /&gt;
:''step'': Number of turns between each explosion.&lt;br /&gt;
:''size'': Either a number or a table of two numbers.  Indicates the size of each explosion.  If a table is supplied, the size is randomly chosen between the range supplied each time an explosion is created.&lt;br /&gt;
:''dice'': Number of d6 dice to use for the damage roll.&lt;br /&gt;
:''content'': ''Optional.'' The content to place in any space where the damage to a space is more than 20 points.  If omitted, nothing will placed.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|setup_targeted_event|dot||integer|step}}&lt;br /&gt;
Runs the setup script for the targeting event.&lt;br /&gt;
:''step'': Number of turns between each monster teleport.&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Modding:Sprites_(0.9.9.7)</id>
		<title>Modding:Sprites (0.9.9.7)</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Modding:Sprites_(0.9.9.7)"/>
				<updated>2025-08-11T12:33:17Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A sprite in DRL is comprised of three distinct components: a color spritesheet, a grayscale version for [[Modding:Color#Color Sets|coloring]], and a black and white version for outlining sans shadow.  Very few sprites make use of all three.&lt;br /&gt;
&lt;br /&gt;
As of this version it is not possible for modders to directly edit sprites so there is no need to go into further detail.  What is needed is a list of sprites that modders can use:&lt;br /&gt;
&lt;br /&gt;
== Player Sprites ==&lt;br /&gt;
Player sprites have colorable armor and change based on wielded weapon.  They are good sprites to use for player-like beings provided you manually handle the corpse.&lt;br /&gt;
&lt;br /&gt;
{{drltable|Player Sprites|1|{{Table1Col&lt;br /&gt;
  |es=background: #333;&lt;br /&gt;
  |c1=vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |SPRITE_PLAYER&lt;br /&gt;
  |SPRITE_PLAYER_KNIFE&lt;br /&gt;
  |SPRITE_PLAYER_CHAINSAW&lt;br /&gt;
  |SPRITE_PLAYER_PISTOL&lt;br /&gt;
  |SPRITE_PLAYER_SHOTGUN&lt;br /&gt;
  |SPRITE_PLAYER_CSHOTGUN&lt;br /&gt;
  |SPRITE_PLAYER_DSHOTGUN&lt;br /&gt;
  |SPRITE_PLAYER_CHAINGUN&lt;br /&gt;
  |SPRITE_PLAYER_BAZOOKA&lt;br /&gt;
  |SPRITE_PLAYER_PLASMA&lt;br /&gt;
  |SPRITE_PLAYER_BFG9000&lt;br /&gt;
  |SPRITE_PLAYER_SPEAR&lt;br /&gt;
  |SPRITE_PLAYER_STAFF&lt;br /&gt;
  |SPRITE_PLAYER_CLEAVER&lt;br /&gt;
  |SPRITE_PLAYER_DRAGON&lt;br /&gt;
  |}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Item Sprites ==&lt;br /&gt;
Armor, non-steel boots, mod packs, skulls, and phase devices are colorable. Choice is otherwise limited.&lt;br /&gt;
&lt;br /&gt;
{{drltable|Item Sprites|1|{{Table1Col&lt;br /&gt;
  |es=background: #333;&lt;br /&gt;
  |c1=vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |SPRITE_KNIFE&lt;br /&gt;
  |SPRITE_CHAINSAW&lt;br /&gt;
  |SPRITE_PISTOL&lt;br /&gt;
  |SPRITE_SHOTGUN&lt;br /&gt;
  |SPRITE_CSHOTGUN&lt;br /&gt;
  |SPRITE_DSHOTGUN&lt;br /&gt;
  |SPRITE_CHAINGUN&lt;br /&gt;
  |SPRITE_BAZOOKA&lt;br /&gt;
  |SPRITE_PLASMA&lt;br /&gt;
  |SPRITE_BFG9000&lt;br /&gt;
  |SPRITE_SPEAR&lt;br /&gt;
  |SPRITE_BFG10K&lt;br /&gt;
  |SPRITE_STAFF&lt;br /&gt;
  |SPRITE_CLEAVER&lt;br /&gt;
  |SPRITE_DRAGON&lt;br /&gt;
  |SPRITE_ARMOR&lt;br /&gt;
  |SPRITE_AARMOR&lt;br /&gt;
  |SPRITE_SBOOTS&lt;br /&gt;
  |SPRITE_BOOTS&lt;br /&gt;
  |SPRITE_MOD&lt;br /&gt;
  |SPRITE_SKULL&lt;br /&gt;
  |SPRITE_AMMO&lt;br /&gt;
  |SPRITE_PAMMO&lt;br /&gt;
  |SPRITE_SHELL&lt;br /&gt;
  |SPRITE_PSHELL&lt;br /&gt;
  |SPRITE_ROCKET&lt;br /&gt;
  |SPRITE_PROCKET&lt;br /&gt;
  |SPRITE_CELL&lt;br /&gt;
  |SPRITE_PCELL&lt;br /&gt;
  |SPRITE_PHASE&lt;br /&gt;
  |SPRITE_BACKPACK&lt;br /&gt;
  |SPRITE_ENVIRO&lt;br /&gt;
  |SPRITE_HGLOBE&lt;br /&gt;
  |SPRITE_LHGLOBE&lt;br /&gt;
  |SPRITE_SUPERCHARGE&lt;br /&gt;
  |SPRITE_INV&lt;br /&gt;
  |SPRITE_MEGASPHERE&lt;br /&gt;
  |SPRITE_SHARD&lt;br /&gt;
  |SPRITE_MEDPACK&lt;br /&gt;
  |SPRITE_LMEDPACK&lt;br /&gt;
  |SPRITE_BERSERK&lt;br /&gt;
  |SPRITE_MAP&lt;br /&gt;
  |SPRITE_TMAP&lt;br /&gt;
  |SPRITE_SCHEMATIC&lt;br /&gt;
  |SPRITE_LIGHTAMP&lt;br /&gt;
  |SPRITE_NUKE&lt;br /&gt;
  |SPRITE_LAVAINV&lt;br /&gt;
  |}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Being Sprites ==&lt;br /&gt;
NoCorpse sprites can be accessed by adding 16 to the parent being, except in the case of oversized sprites--those just add 2.  Lost Souls, pain elementals, and agony elementals do not have corpse sprites.  Both the cyberdemon and mastermind are oversized sprites.&lt;br /&gt;
&lt;br /&gt;
{{drltable|Being Sprites|1|{{Table1Col&lt;br /&gt;
  |es=background: #333;&lt;br /&gt;
  |c1=vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |SPRITE_FORMER&lt;br /&gt;
  |SPRITE_SERGEANT&lt;br /&gt;
  |SPRITE_CAPTAIN&lt;br /&gt;
  |SPRITE_COMMANDO&lt;br /&gt;
  |SPRITE_IMP&lt;br /&gt;
  |SPRITE_DEMON&lt;br /&gt;
  |SPRITE_LOSTSOUL&lt;br /&gt;
  |SPRITE_CACODEMON&lt;br /&gt;
  |SPRITE_PAIN&lt;br /&gt;
  |SPRITE_KNIGHT&lt;br /&gt;
  |SPRITE_BARON&lt;br /&gt;
  |SPRITE_ARACHNO&lt;br /&gt;
  |SPRITE_ARCHVILE&lt;br /&gt;
  |SPRITE_REVENANT&lt;br /&gt;
  |SPRITE_MANCUBUS&lt;br /&gt;
  |SPRITE_BRUISER&lt;br /&gt;
  |SPRITE_AGONY&lt;br /&gt;
  |SPRITE_MASTER&lt;br /&gt;
  |SPRITE_LAVAELEM&lt;br /&gt;
  |SPRITE_ANGEL&lt;br /&gt;
  |SPRITE_SHAMBLER&lt;br /&gt;
  |SPRITE_JC&lt;br /&gt;
  |SPRITE_CYBERDEMON&lt;br /&gt;
  |SPRITE_MASTERMIND&lt;br /&gt;
  |}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Cell Sprites ==&lt;br /&gt;
Many cells have multiple sprite variants that, if you want to access separately will take some trial and error.  Fluids are in a 2x2 square, walls are in a 3x15 vertical rectangle, floors are a 16x1 line, and most other multi-sprite cells are adjacent.&lt;br /&gt;
Stairs, cave walls, brick walls, and the colored boxes are colorable.&lt;br /&gt;
&lt;br /&gt;
{{drltable|Cell Sprites|1|{{Table1Col&lt;br /&gt;
  |es=background: #333;&lt;br /&gt;
  |c1=vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |SPRITE_DOOR&lt;br /&gt;
  |SPRITE_OPENDOOR&lt;br /&gt;
  |SPRITE_HELLDOOR&lt;br /&gt;
  |SPRITE_HELLOPENDOOR&lt;br /&gt;
  |SPRITE_BARREL&lt;br /&gt;
  |SPRITE_LAVABARREL&lt;br /&gt;
  |SPRITE_ACIDBARREL&lt;br /&gt;
  |SPRITE_TREE&lt;br /&gt;
  |SPRITE_GRAYSTAIRS&lt;br /&gt;
  |SPRITE_STAIRS&lt;br /&gt;
  |SPRITE_REDSTAIRS&lt;br /&gt;
  |SPRITE_PORTAL&lt;br /&gt;
  |SPRITE_TELEPORT&lt;br /&gt;
  |SPRITE_LEVER&lt;br /&gt;
  |SPRITE_BLOOD&lt;br /&gt;
  |SPRITE_BLOODPOOL&lt;br /&gt;
  |SPRITE_CORPSE&lt;br /&gt;
  |SPRITE_WALLBLOOD&lt;br /&gt;
  |SPRITE_FLOOR&lt;br /&gt;
  |SPRITE_CAVEFLOOR&lt;br /&gt;
  |SPRITE_HELLFLOOR&lt;br /&gt;
  |SPRITE_WALL&lt;br /&gt;
  |SPRITE_CAVEWALL&lt;br /&gt;
  |SPRITE_BRICKWALL&lt;br /&gt;
  |SPRITE_TECHWALL&lt;br /&gt;
  |SPRITE_BOSSWALL&lt;br /&gt;
  |SPRITE_WATER&lt;br /&gt;
  |SPRITE_ACID&lt;br /&gt;
  |SPRITE_LAVA&lt;br /&gt;
  |SPRITE_BRIDGE&lt;br /&gt;
  |SPRITE_YBOX&lt;br /&gt;
  |SPRITE_WBOX&lt;br /&gt;
  |SPRITE_YBOXC&lt;br /&gt;
  |SPRITE_WBOXC&lt;br /&gt;
  |}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Missile Sprites ==&lt;br /&gt;
There are only a few missile sprites. Color shots and acid shots are colorable.&lt;br /&gt;
{{drltable|Missile Sprites|1|{{Table1Col&lt;br /&gt;
  |es=background: #333;&lt;br /&gt;
  |c1=vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |SPRITE_SHOT&lt;br /&gt;
  |SPRITE_CSHOT&lt;br /&gt;
  |SPRITE_BLAST&lt;br /&gt;
  |SPRITE_ROCKETSHOT&lt;br /&gt;
  |SPRITE_EXPLOSION&lt;br /&gt;
  |SPRITE_PLASMASHOT&lt;br /&gt;
  |SPRITE_BFGSHOT&lt;br /&gt;
  |SPRITE_FIREBALL&lt;br /&gt;
  |SPRITE_PLASMABALL&lt;br /&gt;
  |SPRITE_ACIDSHOT&lt;br /&gt;
  |}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Sprites ==&lt;br /&gt;
These last few sprites are special purpose graphics that may still be of use.  The arrow, select, and mark sprites are colorable.&lt;br /&gt;
{{drltable|Misc Sprites|1|{{Table1Col&lt;br /&gt;
  |es=background: #333;&lt;br /&gt;
  |c1=vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |SPRITE_ARROW&lt;br /&gt;
  |SPRITE_SELECT&lt;br /&gt;
  |SPRITE_MARK&lt;br /&gt;
  |SPRITE_GRID&lt;br /&gt;
  |}}&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Strategy:Dragonslayer</id>
		<title>Strategy:Dragonslayer</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Strategy:Dragonslayer"/>
				<updated>2025-08-11T12:33:12Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
&lt;br /&gt;
=== 0.9.9.7 ===&lt;br /&gt;
The Dragonslayer, perhaps the most elusive weapon, is the hardest weapon to use if you don't know how to obtain it.&lt;br /&gt;
&lt;br /&gt;
A few of the DRL gurus know how to drop both the Berserker Armor and the Dragonslayer every time in a run, but the rest of us are kind of clueless on how to do such a feat.&lt;br /&gt;
&lt;br /&gt;
However, here are some guidelines:&lt;br /&gt;
&lt;br /&gt;
* The Dragonslayer and the Berserker armor are related, but one can actually use the Dragonslayer without the Berserker Armor. The Dragonslayer is required to WEAR the Berserker armor, not vice versa.&lt;br /&gt;
&lt;br /&gt;
* The Dragonslayer will drop in the Unholy Cathedral in place of Azarel's Sycthe when played on Nightmare! (under some extra conditions, possibly on a damageless run?). Unfortunately, no one except those who know exactly how to have been able to pick it up and use it.&lt;br /&gt;
&lt;br /&gt;
* The Berserker Armor can only be worn if you are wielding the Dragonslayer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Not much has been found out about the Dragonslayer. If someone finds out a way to pick up the Dragonslayer reliably, we do not encourage you to post how on this wiki.&lt;br /&gt;
&lt;br /&gt;
[[User:GinDiamond|GinDiamond]] ([[User talk:GinDiamond|talk]]) 21:57, 14 October 2013 (CEST)&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Strategy:Cerberus_armor</id>
		<title>Strategy:Cerberus armor</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Strategy:Cerberus_armor"/>
				<updated>2025-08-11T12:33:04Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
The Cerberus armor may have no [[protection]] value, but it carries a massive 70% [[resistance]] against [[fire]] and [[acid]], and a still tremendous 50% resistance against [[plasma]]. All seasoned DRL players come to learn that resistances are a lot more potent in damage reduction than sheer protection, so don't balk at the Cerberus armor's 0 protection value. An [[Arch-vile]]'s attack that deals a whopping 20 damage with no armor, enough to three shot any class with no [[Ironman]] investment, will deal a rather palatable 6 damage when you have this armor on, only 1 more than you will take with a [[Fireproof armor|Fireproof red armor]]. But then not only would you be tremendously protected against fire, a [[Baron of hell]] wouldn't deal anymore than 6 damage against you at maximum and would usually be dealing around 3-4 damage, when the acid attacks of Barons are notoriously difficult to get good armor to defend against. Then against [[Arachnotron]]s, you'll be only sustaining 1 or 2 damage per hit when you would need armor with a protection value of 6 or more to get this same effect, and against plasma-dealing enemies with single strong hits, you'll see a lot more appreciation with this armor than with just pure defense, due to armor having half protection against plasma, while resistances protect to their full value. So essentially with Cerberus Armor, you get an armor to well protect you against all the most dangerous enemies in the game that you would otherwise have a lot of difficulty in achieving.&lt;br /&gt;
&lt;br /&gt;
The Cerberus Armor does come with a big drawback in its very heavy move [[speed]] and [[knockback]] penalties of -30%. Such a big movement penalty would be the main reason you definitely don't want to ditch all your other armor, as you should be keeping a primary armor for moving around with much better movement, while you reserve this armor for when you're going to get into a big open firefight or otherwise heavily risk walking into the range of one of the aforementioned enemies. Another big potential drawback is that this armor has no innate [[bullet]], [[shrapnel]], and [[melee]] resistance, with it inheriting those resistances from whatever armor you used to make this assembly. So if you used an armor without any of those resistances, your Cerberus armor will end up giving you no protection against them. Bullets don't matter much, but [[Former captain]]s can deal heavy damage when you have no sort of protection against them, and with no shrapnel defense you'll essentially be naked against [[Former sergeant]]s, whose shotguns are actually pretty threatening without armor, while obviously you will get really hurt if you go into an enemy's melee range without any melee defense. This flaw can be fixed though as covered in the next section.&lt;br /&gt;
&lt;br /&gt;
==Which armor to use as a base==&lt;br /&gt;
When it comes to your standard armors, the [[Green armor]] would actually be the best choice, since it does carry a meager 15% bullet and shrapnel resistance, while the [[Blue armor]] and [[Red armor]] have no such resistance against them nor melee. Now this pittance of bullet and shrapnel resistance is barely any better than nothing, so you shouldn't be using a Green over the much better Exotic armor options and only use it as a last resort if you can't get a good Exotic armor, but in that case it's not going to make a real difference over using a Blue or Red armor, so you shouldn't lug a Green around long after they're obsolete just for this possibility.&lt;br /&gt;
&lt;br /&gt;
When it comes to the Exotic armors, you can immediately cross off the [[Energy-shielded vest]], which covers the same set of resistances of the Cerberus armor and will work much better through conventional modding and other assemblies, and the [[Bullet-proof vest]], which only gives you a bullet resistance, while you'll rarely be threatened by bullets unless you somehow get surrounded by a swarm of [[Former captain]]s. [[Phaseshift armor]] provides a decent 30% resistance to bullet/shrapnel/melee, buts its wonderful movement bonus would be lost if you made it Cerberus, which is the most useful and defining part of that armor, so it's strongly advised to not use it for this assembly unless you really need especially strong armor and lack a better base. It is however worth pointing out that if you have the [[Phaseshift boots]] too, a Cerberus Phaseshift armor will still complete the Phaseshift set to provide you with the fluid immunity while the boots will keep your movement speed up, making this an effective combo when it is otherwise normally infeasible to have strong protection and fluid immunity without a severe sacrifice in movement speed. [[Medical armor]] provides an ok 20% resistance to the three physical types, which won't give you amazing Cerberus armor, but can be considered the baseline for acceptable Cerberus bases; if you don't have any of the upcoming superior armors, it'll make a decent Cerberus armor that will give you some protection against melee unlike the Green armor. Plus it will still have its ability to regenerate your health up to 25%, as rarely useful as it is.&lt;br /&gt;
&lt;br /&gt;
[[Duelist armor]] provides a great 50% resistance against the physical trio, which will give you Cerberus armor that will make you take at least half damage against every damage source possible. However its +15% movement speed would be lost in the process, when the Duelist armor is one of the few armors in the game that improves your speed wearing it at base, while being decent armor at base on top of that. With that said, if you don't have the following three armors, and don't mind losing a movement-boosting armor, the Duelist armor will make a good base for this assembly, and the protection-for-movement tradeoff is a lot more favorable here than with the Phaseshift armor. The [[Ballistic vest]] also provides a 50% resistance against the physical trio, so it will result in the same  exact Cerberus that the Duelist armor will result in. However with it having no movement bonus and having a lower armor rating than the Duelist armor, the Ballistic vest is the inferior armor by itself and would have nothing to offer you if you made Duelist Cerberus, while in the vice versa scenario the Duelist armor will still have its own use for movement while the Cerberus Ballistic will be just as effective. So in the scenario that you have both of them, turn the Ballistic vest Cerberus, and if you just have the Ballistic, it'll make a a great base while you'll lose nothing important by turning it Cerberus. &lt;br /&gt;
&lt;br /&gt;
Now for the really good bases, there's [[Onyx armor]]. Onyx armor provides no resistances of its own, giving you a baseline Cerberus armor, but one other aspect of this assembly that gets carried over is durability. Normally this doesn't matter as you just get the typical 100% durability nearly every armor tends to have naturally. But since the Onyx armor has infinite durability, the Cerberus armor you make out of it will also have infinite durability without you needing to use an [[Onyx mod]], which not only gets you good indestructible armor without an Onyx mod (or saves you a valuable Onyx mod if you already had one), but also nets you infinite durability while saving a mod slot for your Cerberus armor to farther improve it (which will be covered in a bit). With Onyx Cerberus you will never have to worry about Barons and Arachnotrons destroying your armor again, and will have guaranteed strong protection against the VMR for the rest of your run no matter how badly you get beaten up. Then the absolute best choice for a base is [[Gothic armor]]; you get the great 50% physical resistances to the physical trio that Duelist armor and Ballistic vest give you, while the 200% durability is kept, so you get great protection against everything, on top of boosted durability. Additionally, using Gothic as a base means the Cerberus' set speed and knockback penalty are actually beneficial, as they're substantially better than the Gothic's, so making your Gothic armor Cerberus will give you a speed gain over twice as much as applying an [[Agility mod]] to the Gothic armor would. Making the Gothic Cerberus grants you a better result than every other possible base, while being an unquestionable improvement over the base armor itself. For one more note with the Gothic armor, if you also find the [[Gothic boots]], wearing both together will form the Gothic Arms set, which increases your armor's protection by 4. Normally the fact that set makes you completely immobile makes it impractical, but alongside Cerberus Gothic armor, it'll reduce an [[Arch-vile]]'s attack down to 2 damage (or 1 if you P-modded it or have any [[Strategy:Tough as Nails|Tough as Nails]] investment), while providing you the best acid protection any armor can have and the best plasma protection short of an [[Energy shield]], [[Plasma shield]], or [[Nanofiber skin]] [[Energy-shielded vest]], thus there are situations where it can be useful (such as an unescapable open fight where you need out to out-DPS a ton of enemies to live) and so is one more perk of Gothic Cerberus armor.&lt;br /&gt;
&lt;br /&gt;
If you're a Technician and happen to find it, the [[Cybernetic Armor]] is one more option. It comes with 50% resistance to the physical trio, so it's another possible option to get the coveted &amp;gt;=50% resistance to all possible damage Cerberus armor, plus it already has the -30% speed and knockback penalities of Cerberus armor so it's no loss there. However its massive base protection of 7 is lost, and much more importantly, it's an armor that can never be unequipped while also featuring normal durability with no regeneration. Duelist, Ballistic, and Gothic Cerberus will provide just as much protection while being able to be unequipped if they get damaged, while the [[Nanofiber skin armor]] and [[Cybernano armor]] assemblies would be better options for an armor you can never unequip, as they still provide great protection while ensuring you won't have to ever worry about being trapped in a depleted armor. If you inadvertently put the Cybernetic armor on though as a Technician and don't have a Nano mod to make those assemblies, you might as well turn it Cerberus as resistances are still king and you'll be a lot more protected against the most dangerous enemies. Otherwise only use the Cybernetic as a base if you don't have any of the good Exotic armors to use and are really desperate for such strong protection over all else. If you decide to put on the Cybernetic to make it Cerberus, you will want to prioritise putting on an Onyx or Nano mod if you have one of them to ensure durability won't be an issue.&lt;br /&gt;
&lt;br /&gt;
==Modding==&lt;br /&gt;
Since you need [[Whizkid]] 2 to make Cerberus armor, you will be able to apply a single mod to it.&lt;br /&gt;
&lt;br /&gt;
The [[Power mod]] is an obvious choice, as it raises the armor's natural defense of 0 to 2. When the resistances lower the damage dealt so much, this +2 armor can provide a big difference in additional survivability; e.g. with base Cerberus armor it will take an Arch-vile 9 hits to kill a Scout/Technician without any [[Ironman]] investment, while with the armor P-modded, it'll take the Arch-vile 13 hits, increasing your armor's protection abilities over 40%. Plus if you made Cerberus with a base that provides no physical resistances, this will ensure you still will have some sort of protection against melee and Formers. &lt;br /&gt;
&lt;br /&gt;
A Power mod is in stiff competition with an [[Agility mod]] however, as that Agility mod will make the movement speed penalty of the Cerberus armor a much more tolerable -15% (which for reference, is better than a base Red armor's -20%). For which mod to use, it depends on if your build values damage avoidance or damage tanking more, but the less melee resistance your Cerberus has, the more appealing a Power mod is to help cover up the gaping hole in your protection. Additionally if you already have another armor with much greater movement speed that you primarily wear while you mainly reserve your Cerberus Armor for unavoidable open fights and emergencies, you will probably also find better value in beefing up its protection over making it less slow.&lt;br /&gt;
&lt;br /&gt;
A [[Technical mod]] is useless when why would you want to increase the knockback penalty even more when it's already so stiff, especially when you can improve its protection or movement speed substantially instead.&lt;br /&gt;
&lt;br /&gt;
A [[Bulk mod]] is of questionable use, when your Cerberus should be able to usually last between [[Armor shard]]s and making its speed even worse really hurts. Plus a Power mod will indirectly significantly increase durability too through its damage reduction without costing you any more speed. Don't even think about using up your only mod spot on a Bulk mod with the Gothic Cerberus; you'll have to be playing really reckless or have gotten into some deep shit for 200% durability of Gothic Cerberus to not be enough on top of a Power or Agility mod. &lt;br /&gt;
&lt;br /&gt;
A [[Nano mod]] will pretty much ensure your Cerberus will never face durability issues and will not be a bad use of your mod slot, but that Nano mod can probably be put to better use elsewhere in making yourself a broken weapon that eliminates ammo concerns or [[Antigrav boots]] to get yourself unmatchable movement speed.&lt;br /&gt;
&lt;br /&gt;
An [[Onyx mod]] would make your Cerberus indestructible, but good Cerberus is pretty durable as is and you'll have to give up a really valuable Power or Agility mod boost for it. It might be more worth using it on another valuable but more fragile armor instead, it'll depend on the build you're running. Such as if you're running an extreme tanking build that will soak up a huge amount of unavoidable damage like a [[Vampyre]] build, then indestructible Cerberus could be more valuable to you over the other modding options. And needless to say, it has no effect on Onyx Cerberus, and would be quite wasteful on a Gothic Cerberus. [[User:Omega Tyrant|Omega Tyrant]] ([[User talk:Omega Tyrant|talk]]) 18:23, 23 April 2017 (UTC)&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Modding:being_API_(0.9.9.6)</id>
		<title>Modding:being API (0.9.9.6)</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Modding:being_API_(0.9.9.6)"/>
				<updated>2025-08-11T12:32:59Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== API ==&lt;br /&gt;
The [[Modding:Thing#API|Thing API]] can also be used with beings.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;border: 2px solid darkred; border-spacing: 0; font-size: 90%; margin: 0.25em 0.5em;&amp;quot;&lt;br /&gt;
 ! colspan=&amp;quot;2&amp;quot; style=&amp;quot;background: darkred; color: yellow; font-size: 120%; text-align: center&amp;quot;|Being Interface&lt;br /&gt;
 {{Table2Col&lt;br /&gt;
  |es=background: #333;&lt;br /&gt;
  |c1=font-weight:bold; text-align:right; vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |c2=padding:0px 2px;&lt;br /&gt;
  |[[Modding:Being|Being]]|being.[[#being_new|new]]([[Modding:Being|Being ID]] id) &lt;br /&gt;
  |'''void'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_destroy|destroy]]('''boolean''' silent) &lt;br /&gt;
  |'''void'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_kill|kill]]('''boolean''' overkill) &lt;br /&gt;
  |'''void'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_ressurect|ressurect]]('''integer''' rrange) &lt;br /&gt;
  |'''void'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_apply_damage|apply_damage]]('''integer''' damage, [[Modding:Constants#BodyTarget|BodyTarget]] target, [[Modding:Constants#DamageType|DamageType]] damageType) &lt;br /&gt;
  |'''string'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_get_name|get_name]]('''boolean''' known, '''boolean''' capitalized) &lt;br /&gt;
  |[[Modding:Item|Item]]|[[Modding:Being|Being]]&amp;amp;#058;[[#being_get_inv_item|get_inv_item]]('''integer''' slot) &lt;br /&gt;
  |'''void'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_set_inv_item|set_inv_item]]('''integer''' slot, [[Modding:Item|Item]] item) &lt;br /&gt;
  |[[Modding:Item|Item]]|[[Modding:Being|Being]]&amp;amp;#058;[[#being_get_eq_item|get_eq_item]]([[Modding:Constants#Equip Slots|Equip Slot]] slot) &lt;br /&gt;
  |'''void'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_set_eq_item|set_eq_item]]([[Modding:Constants#Equip Slots|Equip Slot]] slot, [[Modding:Item|Item]] item) &lt;br /&gt;
  |'''void'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_play_sound|play_sound]]('''Sound ID''' sound) &lt;br /&gt;
  |'''integer'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_get_total_resistance|get_total_resistance]]([[Modding:Constants#Resistance|Resistance]] resistance, [[Modding:Constants#BodyTarget|BodyTarget]] target) &lt;br /&gt;
  |'''boolean'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_use|use]]('''integer''' slot) &lt;br /&gt;
  |'''boolean'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_wear|wear]]('''integer''' slot) &lt;br /&gt;
  |'''boolean'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_pickup|pickup]]([[Modding:Coord|Coord]] pos) &lt;br /&gt;
  |'''void'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_attack|attack]]([[Modding:Coord|Coord]] or [[Modding:Being|Being]] target) &lt;br /&gt;
  |'''void'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_fire|fire]]([[Modding:Coord|Coord]] target, [[Modding:Item|Item]] weapon) &lt;br /&gt;
  |'''boolean'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_reload|reload]]() &lt;br /&gt;
  |'''integer'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_direct_seek|direct_seek]]([[Modding:Coord|Coord]] target) &lt;br /&gt;
  |'''boolean'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_path_find|path_find]]([[Modding:Coord|Coord]] target, '''integer''' cutoff, '''integer''' maximum) &lt;br /&gt;
  |'''integer'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_path_next|path_next]]() &lt;br /&gt;
  |[[Modding:Coord|Coord]]|[[Modding:Being|Being]]&amp;amp;#058;[[#being_flock_target|flock_target]]('''integer''' range, '''integer''' mind, '''integer''' maxd) &lt;br /&gt;
  |'''void'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_msg|msg]]('''string''' msg_player, '''string''' msg_being) &lt;br /&gt;
  |[[Modding:Item|Item]]|[[Modding:Being|Being]]&amp;amp;#058;[[#being_select_slot_by_letter|select_slot_by_letter]]('''string''' letter) &lt;br /&gt;
  |'''void'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_phase|phase]]([[Modding:Cell|Cell ID]] cell) &lt;br /&gt;
  |'''void'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_spawn|spawn]]([[Modding:Being|Being ID]] being) &lt;br /&gt;
  |'''boolean'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_is_visible|is_visible]]() &lt;br /&gt;
  |'''boolean'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_is_player|is_player]]() &lt;br /&gt;
  |'''integer'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_set_items|set_items]]([[Modding:ItemSet|ItemSet]] set) &lt;br /&gt;
  |'''void'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_nuke|nuke]]('''integer''' time) &lt;br /&gt;
  |[[Modding:Item|Item]], '''boolean'''|[[Modding:Being|Being]]&amp;amp;#058;[[#being_pick_mod_item|pick_mod_item]]('''string''' modletter, '''integer''' techbonus)&lt;br /&gt;
  |}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Anchor|being_new}}&lt;br /&gt;
;being.new([[Modding:Being|Being ID]] id) &amp;amp;rarr; [[Modding:Being|Being]]&lt;br /&gt;
:This creates a newly allocated being of the appropriate type. The being won't exist on the map until it is placed by e.g. Level.drop_being.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_destroy}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;destroy('''boolean''' silent) &lt;br /&gt;
:Deallocates the memory associated with the being and removes it from the level (if applicable). The normal results of killing a being (e.g. leaving a corpse) are ignored. The ''silent'' parameter is optional. If true, applicable OnKill and OnKillAll hooks and events will also be ignored.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_kill}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;kill('''boolean''' overkill) &lt;br /&gt;
:Kills the being. If the optional ''overkill'' parameter is true, then the being will be gibbed.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_ressurect}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;ressurect('''integer''' rrange) &lt;br /&gt;
:Resurrects a single corpse that is found within a square of side-length 2 &amp;amp;times; ''rrange'' + 1, centered around the being. Nearer corpses are preferred. The corpse must not have another being standing on it and must be within sight of the being (as determined by the enemy line-of-sight algorithm). The resurrected being (if any) will have BF_NOEXP set. Messages are included.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_apply_damage}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;apply_damage('''integer''' damage, [[Modding:Constants#BodyTarget|BodyTarget]] target, [[Modding:Constants#DamageType|DamageType]] damageType) &lt;br /&gt;
:Deals damage to the being using the given body target and damage type. (The default damage type is bullet damage.)&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_get_name}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;get_name('''boolean''' known, '''boolean''' capitalized) &amp;amp;rarr; '''string'''&lt;br /&gt;
:Returns the name of the being. If ''known'' is true, &amp;quot;the&amp;quot; is added, otherwise &amp;quot;a&amp;quot; or &amp;quot;an&amp;quot; is added. If BF_UNIQUENAME is set for the being, then no article is used in either case. If ''capitalized'' is true, then the first letter will be capitalized.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_get_inv_item}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;get_inv_item('''integer''' slot) &amp;amp;rarr; [[Modding:Item|Item]]&lt;br /&gt;
;[[Modding:Being|Being]].inv&amp;amp;#091;'''integer''' slot] &amp;amp;rarr; [[Modding:Item|Item]]&lt;br /&gt;
:Returns the item in the given slot in the being's inventory. If the slot is empty, nil is returned instead.  &lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_set_inv_item}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;set_inv_item('''integer''' slot, [[Modding:Item|Item]] item) &lt;br /&gt;
;[[Modding:Being|Being]].inv&amp;amp;#091;'''integer''' slot] = [[Modding:Item|Item]] item &lt;br /&gt;
:Sets the given slot in the being's inventory to the given item. If the slot wasn't empty before, the previous constents are lost.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_get_eq_item}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;get_eq_item([[Modding:Constants#Equip Slots|Equip Slot]] slot) &amp;amp;rarr; [[Modding:Item|Item]]&lt;br /&gt;
;[[Modding:Being|Being]].eq&amp;amp;#091;[[Modding:Constants#Equip Slots|Equip Slot]] slot] &amp;amp;rarr; [[Modding:Item|Item]]&lt;br /&gt;
:Returns the item in the given equipment slot of the being. If the slot is empty, nil is returned instead. There are additional shorthands for each equipment slot: the ''eq'' table has .weapon, .prepared, .armor, and .boots fields.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_set_eq_item}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;set_eq_item([[Modding:Constants#Equip Slots|Equip Slot]] slot, [[Modding:Item|Item]] item) &lt;br /&gt;
;[[Modding:Being|Being]].eq&amp;amp;#091;[[Modding:Constants#Equip Slots|Equip Slot]] slot] = [[Modding:Item|Item]] item &lt;br /&gt;
:Sets the being's equipment slot to the given item. Any item that was previously in that slot is lost. There are additional shorthands for each equipment slot: the ''eq'' table has .weapon, .prepared, .armor, and .boots fields.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_play_sound}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;play_sound('''Sound ID''' sound) &lt;br /&gt;
:Plays the given sound as if it came from the being's position.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_get_total_resistance}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;get_total_resistance([[Modding:Constants#Resistance|Resistance]] resistance, [[Modding:Constants#BodyTarget|BodyTarget]] target) &amp;amp;rarr; '''integer'''&lt;br /&gt;
:Calculates the being's effective resistance against attacks of the given target (default is body). This accounts for inherent resists as well as equipment bonuses.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_use}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;use('''integer''' slot) &amp;amp;rarr; '''boolean'''&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;use([[Modding:Item|Item]] item) &amp;amp;rarr; '''boolean'''&lt;br /&gt;
:This makes the being use the given consumable item from its inventory. The function always returns false. (Bug: it is supposed to return true on success.)&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_wear}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;wear('''integer''' slot) &amp;amp;rarr; '''boolean'''&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;wear([[Modding:Item|Item]] item) &amp;amp;rarr; '''boolean'''&lt;br /&gt;
:This makes the being wear the given eqipment from its inventory. Returns true on success and false on failure.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_pickup}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;pickup([[Modding:Coord|Coord]] pos) &amp;amp;rarr; '''boolean'''&lt;br /&gt;
:This makes the being pick up the item at the given position. ''pos'' is optional; it defaults to the being's position. Returns true on success and false on failure.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_attack}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;attack([[Modding:Coord|Coord]] or [[Modding:Being|Being]] target) &lt;br /&gt;
:This makes the being do a standard melee attack against the targeted being or coord.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_fire}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;fire([[Modding:Coord|Coord]] target, [[Modding:Item|Item]] weapon) &lt;br /&gt;
:This makes the being fire at ''target'' with ''weapon''.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_reload}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;reload() &amp;amp;rarr; '''boolean'''&lt;br /&gt;
:This makes the being reload its currently equipped weapon. The return value is true if there being had at least some of the appropriate ammo to attempt reloading with.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_direct_seek}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;direct_seek([[Modding:Coord|Coord]] target) &amp;amp;rarr; '''integer'''&lt;br /&gt;
:This makes the being take a step towards the target. The being will always try to travel in a direct path. The return value is either 0, 1, 2, or 3. 0 indicates success, 1 indicates that a wall blocked the move, 2 indicates that a door blocked the move, and 3 indicates that a being blocked the move.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_path_find}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;path_find([[Modding:Coord|Coord]] target, '''integer''' cutoff, '''integer''' maximum) &amp;amp;rarr; '''boolean'''&lt;br /&gt;
:This attempts to calculate a path between the being and ''target''. The ''cutoff'' and ''maximum'' parameters are somewhat technical, but basically they indicate how much time should be spend searching for a path. DRL uses 40, 200 for bosses and 10, 40 for normal enemies. The path will be remembered by the being, and can be followed using path_next. Modders should keep in mind that path-finding is a somewhat expensive operation, especially for large ''cutoff'' and ''maximum''. The return value indicates whether a path was found. Even if no path was found, a path will be loaded that will try to take the being closer to the target (although this path may be empty). This uses the AStar searching algorithm using Euclidean distance as a heuristic. The search is aborted if ''maximum'' nodes are expanded without finding the target or it ''cutoff'' nodes are expanded without getting closer to the target. When aborted, a path is created to the closest expanded node to the target in terms of the heuristic.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_path_next}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;path_next() &amp;amp;rarr; '''integer'''&lt;br /&gt;
:This causes the being to take a step along the path last calculated by path_find. The return value follows the pattern of direct_seek.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_flock_target}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;flock_target('''integer''' range, '''integer''' mind, '''integer''' maxd) &amp;amp;rarr; [[Modding:Coord|Coord]]&lt;br /&gt;
:This looks for the closest being of the same type to the being (within a square ''range''). If the being is farther than ''maxd'' away, then its position is returned. If it is closer than ''mind'', then a position opposite from the closest with respect to the being is returned. Otherwise (or if there is no nearby being of the same type), a random coord from the scanning area is returned.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_msg}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;msg('''string''' msg_player, '''string''' msg_being) &lt;br /&gt;
:If the being is the player, then ''msg_player'' is displayed. If the being is not the player, but visible to the player, the ''msg_being'' is displayed. If either message is nil it is ignored.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_select_slot_by_letter}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;select_slot_by_letter('''string''' letter) &amp;amp;rarr; [[Modding:Item|Item]]&lt;br /&gt;
:Returns the one of the being's equipment where &amp;quot;a&amp;quot; is for armor, &amp;quot;b&amp;quot; is for boots, &amp;quot;w&amp;quot; is for weapon, and &amp;quot;p&amp;quot; is for the prepared slot. If the slot is empty, nil is returned.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_phase}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;phase([[Modding:Cell|Cell ID]] cell) &lt;br /&gt;
:If ''cell'' is omitted, then the being is displaced randomly as if it used a [[phase device]] (without the flashy interface stuff). If the cell is included, the being is displaced to a random cell of the given cell id. If the chosen cell is occupied, a nearby cell is used. If no such cell exists, a random cell is chosen.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_spawn}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;spawn([[Modding:Being|Being ID]] being) &lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;spawn([[Modding:Being|Being]] being) &lt;br /&gt;
:Drops a new being of the appropriate type (or the given being) nearby. The dropped being is set with the BF_NOEXP flag.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_is_visible}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;is_visible() &amp;amp;rarr; '''boolean'''&lt;br /&gt;
:Determines if the player can see the being.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_is_player}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;is_player() &amp;amp;rarr; '''boolean'''&lt;br /&gt;
:Determines if the being is the player.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_set_items}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;set_items([[Modding:ItemSet|ItemSet]] set) &amp;amp;rarr; '''integer'''&lt;br /&gt;
:Counts the number of the being's equipped items that belong to the given set.&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_nuke}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;nuke('''integer''' time) &lt;br /&gt;
:Sets the nuke timer to ''time'' and changes the cell under the being to the nuke cell. By default, ''time'' is 1. (Setting the nuke time to 0 will disable the countdown.)&lt;br /&gt;
----&lt;br /&gt;
{{Anchor|being_pick_mod_item}}&lt;br /&gt;
;[[Modding:Being|Being]]&amp;amp;#058;pick_mod_item('''string''' modletter, '''integer''' techbonus) &amp;amp;rarr; [[Modding:Item|Item]], '''boolean'''&lt;br /&gt;
:This only works for the player. This gives the player the item select menu used by mods, and calculates whether the mod is legal (using the given ''techbonus''). This includes assembly checking. The first return value is the item on success. The second return value is true on&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Modding:generator_API_(0.9.9.6)</id>
		<title>Modding:generator API (0.9.9.6)</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Modding:generator_API_(0.9.9.6)"/>
				<updated>2025-08-11T12:32:27Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The generator holds all of the ever-present functions used to create the random maps in DRL. It also contains a variety of helper functions, many of them useful if not vital to the creation of intricate and meticulous game design.&lt;br /&gt;
&lt;br /&gt;
== API ==&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;border: 2px solid darkred; border-spacing: 0; font-size: 90%; margin: 0.25em 0.5em;&amp;quot;&lt;br /&gt;
 ! colspan=&amp;quot;2&amp;quot; style=&amp;quot;background: darkred; color: yellow; font-size: 120%; text-align: center&amp;quot;|'''Level Interface'''&lt;br /&gt;
 {{Table2Col&lt;br /&gt;
  |es=background: #333; &lt;br /&gt;
  |c1=font-weight:bold; text-align:right; vertical-align:top; padding:0px 2px;&lt;br /&gt;
  |c2=padding:0px 2px;&lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|safe_empty_coord|dot}} &lt;br /&gt;
  |{{modarg|Coord}}|{{moddef|list|standard_empty_coord|dot}} &lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|set_permanence|dot||Area|ar|boolean|val|Cell|tile}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|setup_ice_event|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|setup_perma_event|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|setup_alarm_event|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|setup_deadly_air_event|dot||integer|step}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|setup_nuke_event|dot||integer|minutes}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|setup_flood_event|dot||integer|direction|integer|step|Cell|cell|boolean|pure}}&lt;br /&gt;
  |{{modarg|integer}}|{{moddef|list|being_weight|dot}}&lt;br /&gt;
  |{{modarg|integer}}|{{moddef|list|item_amount|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|restore_walls|dot||Cell|wall_cell|boolean|keep_fluids}}&lt;br /&gt;
  |{{modarg|Cellset list}}|{{moddef|list|cell_set|dot||list|list}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|horiz_river|dot||Cell|cell|integer|width|boolean|bridge}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|vert_river|dot||Cell|cell|integer|width|boolean|bridge|Coord|pos}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_rivers|dot||boolean|allow_horiz|boolean|allow_more}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|drunkard_walk|dot||Coord|start|integer|steps|Cell|cell|Cell list|ignore|boolean|break_on_edge}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|drunkard_walks|dot||integer|amount|integer|steps|Cell|cell|Cell list|ignore|boolean|break_on_edge|Area|drunk_area}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|contd_drunkard_walks|dot||integer|amount|integer|steps|Cell|cell|Coord|edges1|Coord|edges2|Cell list|ignore|boolean|break_on_edge}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|plot_lines|dot||Coord|where|Area|larea|boolean|horiz|Cell|cell|Cell list|block}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|maze_dungeon|dot||Cell|floor_cell|Cell|wall_cell|integer|granularity|integer|tries|integer|minl|integer|maxl}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|warehouse_fill|dot||Cell|wall_cell|Area|fill_area|integer|box_size|integer|amount}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|warehouse_dungeon|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|add_room|dot||Area|room}}&lt;br /&gt;
  |{{modarg|boolean}}|{{moddef|list|add_rooms|dot}}&lt;br /&gt;
  |{{modarg|Room}}|{{moddef|list|get_room|dot||integer|min_size|integer|max_x|integer|max_y}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_tiled|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_warehouse_dungeon|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_tiled_dungeon|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_tiled_arena_dungeon|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_city_dungeon|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_maze_dungeon|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_archi_dungeon|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_caves_dungeon|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_arena_dungeon|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_fluids|dot||Area|drunk_area}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_barrels|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_stairs|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_special_stairs|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_lever_room|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_teleport_room|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_ammo_room|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_basain|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_warehouse_room|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|generate_vault|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|add_room_feature|dot||boolean|no_monsters}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|handle_rooms|dot||boolean|no_monsters}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|place_player|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|roll_event|dot}}&lt;br /&gt;
  |{{modarg|void}}|{{moddef|list|reset|dot}}&lt;br /&gt;
  |}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
;{{moddef|desc|safe_empty_coord|dot}} &lt;br /&gt;
:Gives a coordinate that satisfies all [[Modding:Constants#Empty Flags|empty flags]]. If one cannot be found, another attempt is made that excludes EF_NOSAFE; if one still cannot be found, another attempt is made that additionally excludes EF_NOSTAIRS and EF_NOHARM.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|standard_empty_coord|dot}} &lt;br /&gt;
:Gives a coordinate that satisfies all empty flags other than EF_NOSAFE.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|set_permanence|dot||Area|ar|boolean|val|Cell|tile}}&lt;br /&gt;
:Adds the &amp;quot;frozen&amp;quot; level event to the map and records it in the mortem history. Levels with the frozen event change all walls into ice walls and all fluids into water.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|setup_ice_event|dot}}&lt;br /&gt;
:Adds the &amp;quot;frozen&amp;quot; level event to the map and records it in the mortem history. Levels with the frozen event change all walls into ice walls and all fluids into water.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|setup_perma_event|dot}}&lt;br /&gt;
:Adds the &amp;quot;sturdy&amp;quot; level event to the map and records it in the mortem history. Levels with the sturdy event set all wall tiles to be permanent.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|setup_alarm_event|dot}}&lt;br /&gt;
:Adds the &amp;quot;alarm&amp;quot; level event to the map and records it in the mortem history. Levels with the alarm event set all non-player beings' [[Modding:Constants#Being Flags|BF_HUNTING]] flag to true.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|setup_deadly_air_event|dot||integer|step}}&lt;br /&gt;
:Adds the &amp;quot;deadly air&amp;quot; event to the map and records it in the mortem history. Levels with the deadly air event cause all beings to lose hit points every '''step''' turns.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|setup_nuke_event|dot||integer|minutes}}&lt;br /&gt;
:Adds the &amp;quot;armed nuke&amp;quot; event to the map and records it in the mortem history. Levels with the armed nuke event begin with a [[thermonuclear bomb]] set at the player's starting position, which will explode in ''minutes'' game minutes.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|setup_flood_event|dot||integer|direction|integer|step|Cell|cell|boolean|pure}}&lt;br /&gt;
:Adds the &amp;quot;flood&amp;quot; event to the map and records it in the mortem history. Levels with the flood event are slowly filled with a fluid: ''direction'' determines whether the floor travels from the right (-1) or from the left (+1); every ''step'' turns, ''cell'' will replace all tiles in a next column to be flooded. Setting ''pure'' to false will move the player and stairs to opposite sides of the map, with the player nearest the flood.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|being_weight|dot|integer}}&lt;br /&gt;
:Gives a value equal to the difficulty-adjusted weight of beings for a given danger level. These are the results used for the base game's monster generation parameters.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|item_amount|dot|integer}}&lt;br /&gt;
:Gives a value equal to the number of items spawned for a given danger level. On level types where the this amount isn't preset, this is the result used for the base game's item generation parameters.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|restore_walls|dot||Cell|wall_cell|boolean|keep_fluids}}&lt;br /&gt;
:Sets all cells on the edge of the map to ''wall_cell''. If ''keep_fluids'' is set to true, fluid tiles will be maintained but set as permanent.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|cell_set|dot|Cellset list|list|list}}&lt;br /&gt;
:Creates a cellset for all cells in ''list''. The returned list functions just like any [[Modding:Constants#Cellsets|CELLSET constant]].&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|horiz_river|dot||Cell|cell|integer|width|boolean|bridge}}&lt;br /&gt;
:Adds a horizontal river to the map, created using ''cell'' tiles. ''width'' sets the tile-width of the river. If ''bridge'' is set to true, a non-fluid floor bridge will be created on the river.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|vert_river|dot||Cell|cell|integer|width|boolean|bridge|Coord|pos}}&lt;br /&gt;
;{{moddef|desc|vert_river|dot||Cell|cell|integer|width|boolean|bridge|integer|pos}}&lt;br /&gt;
:Adds a vertical river to the map, created using ''cell'' tiles. ''width'' sets the tile-width of the river, and ''pos'' sets the starting position of the river. If ''pos'' is given as an integer, then the starting y-coordinate of the river is at the top of the map. If ''bridge'' is set to true, a non-fluid floor bridge will be created on the river.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_rivers|dot||boolean|allow_horiz|boolean|allow_more}}&lt;br /&gt;
:Generates a random number of horizontal and vertical rivers on the map. See [[Fluids#Rivers|Rivers]] for more information. The fluid type varies with map depth.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|drunkard_walk|dot||Coord|start|integer|steps|Cell|cell|Cell list|ignore|boolean|break_on_edge}}&lt;br /&gt;
:Generates ''cell'' tiles according to a drunken walk algorithm. It travels ''steps'' times, starting at the coordinate ''start''. Any cells in ''ignore'' will not be set over but the algorithm will still continue. If ''break_on_edge'' is set to true, the drunken walk will stop if it hits a map border: otherwise it will continue, clamping cells within the map as necessary.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|drunkard_walks|dot||integer|amount|integer|steps|Cell|cell|Cell list|ignore|boolean|break_on_edge|Area|drunk_area}}&lt;br /&gt;
:As Generator.drunkard_walk, but repeated ''amount'' times. Additionally, rather than specifically a starting position, all walks are chosen from a random coordinate within ''drunk_area''.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|contd_drunkard_walks|dot||integer|amount|integer|steps|Cell|cell|Coord|edges1|Coord|edges2|Cell list|ignore|boolean|break_on_edge}}&lt;br /&gt;
:As Generator.drunkard_walks, but rather than limiting the walk's starting position, the walk will stop prematurely if it has reached the x- or y-coordinates of both ''edges1'' and ''edges2''.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|plot_lines|dot||Coord|where|Area|larea|boolean|horiz|Cell|cell|Cell list|block}}&lt;br /&gt;
:Generates a line of ''cell'' tiles on the map, starting at ''where'' and extending to the boundaries of ''larea''. ''horiz'' set to true will produce horizontal lines: otherwise it will produce vertical lines. If a cell from ''block'' is found, the line will end prematurely at the end on which it was blocked.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|maze_dungeon|dot||Cell|floor_cell|Cell|wall_cell|integer|granularity|integer|tries|integer|minl|integer|maxl}}&lt;br /&gt;
:Generates a map-wide maze, using ''wall_cell'' as the wall tiles and ''floor_cell'' as the floor tiles. Wall corridors are at least ''minl'' tiles apart and at most ''maxl'' tiles apart: ''granularity'' sets a rough complexity of the map. The number of walls attempted to be made is equal to ''tries''.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|warehouse_fill|dot||Cell|wall_cell|Area|fill_area|integer|box_size|integer|amount}}&lt;br /&gt;
:Generates ''wall_cell'' tiles in the shape of a square within ''fill_area''. ''boxsize'' sets the size of the side of a box, and ''amount'' sets the number of tries for boxes to be added.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|warehouse_dungeon|dot}}&lt;br /&gt;
:Generates a map-wide warehouse setting. Warehouse dungeons are divided into three large rooms, each attempting 50 tries with boxes of side length 3.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|add_room|dot||Area|room}}&lt;br /&gt;
:Adds ''room'' to the Generator.room_list and Generator.room_meta lists. This is used in conjunction with room generation functions.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|add_rooms|dot|boolean}}&lt;br /&gt;
:As Generator.add_room, but locates all rooms on the map and adds them to Generator.room_list and Generator.room_meta instead.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|get_room|dot|Room|integer|min_size|integer|max_x|integer|max_y}}&lt;br /&gt;
:Finds a room that contains at least ''min_size'' in both height and width, and has a width and height no bigger than ''max_x'' and ''max_y'', respectively.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_tiled|dot}}&lt;br /&gt;
:Generates a &amp;quot;normal&amp;quot; map. Normal levels are divided randomly into rectangular rooms.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_warehouse_dungeon|dot}}&lt;br /&gt;
:Builds a &amp;quot;warehouse&amp;quot; level. This includes everything necessary to be played as a typical random level.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_tiled_dungeon|dot}}&lt;br /&gt;
:Builds a &amp;quot;normal&amp;quot; level. This includes everything necessary to be played as a typical random level.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_tiled_arena_dungeon|dot}}&lt;br /&gt;
:Builds a &amp;quot;single-monster&amp;quot; level. This includes everything necessary to be played as a typical random level.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_city_dungeon|dot}}&lt;br /&gt;
:Builds a &amp;quot;city&amp;quot; level. This includes everything necessary to be played as a typical random level.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_maze_dungeon|dot}}&lt;br /&gt;
:Builds a &amp;quot;maze&amp;quot; level. This includes everything necessary to be played as a typical random level.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_archi_dungeon|dot}}&lt;br /&gt;
:Builds an &amp;quot;archi&amp;quot; level. This includes everything necessary to be played as a typical random level.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_caves_dungeon|dot}}&lt;br /&gt;
:Builds a &amp;quot;cave&amp;quot; level. This includes everything necessary to be played as a typical random level.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_arena_dungeon|dot}}&lt;br /&gt;
:Builds an &amp;quot;arena&amp;quot; level. This includes everything necessary to be played as a typical random level.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_fluids|dot||Area|drunk_area}}&lt;br /&gt;
:Generates all non-river fluids on the map using drunken walks, within ''drunk_area''. The fluid type varies with danger level.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_barrels|dot}}&lt;br /&gt;
:Generates all barrels on the map, The barrel type varies with danger level.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_stairs|dot}}&lt;br /&gt;
:Generates stairs on the map.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_special_stairs|dot}}&lt;br /&gt;
:Generates special stairs on the map, if a special level exists at the current map depth.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_lever_room|dot}}&lt;br /&gt;
:Finds a room of appropriate size and adjusts it into a lever room.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_teleport_room|dot}}&lt;br /&gt;
:Finds a room of appropriate size and adjusts it into a teleporter room.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_ammo_room|dot}}&lt;br /&gt;
:Finds a room of appropriate size and adjusts it into an ammo room. The type of ammo varies with danger level.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_basain|dot}}&lt;br /&gt;
:Finds a room of appropriate size and adjusts it into a room filled with fluid.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_warehouse_room|dot}}&lt;br /&gt;
:Finds a room of appropriate size and adjusts it into a room with boxes (as Generator.warehouse_fill).&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|generate_vault|dot}}&lt;br /&gt;
:Finds a room of appropriate size and adjust it into a vault. The monsters, items, and type of vault vary with danger level.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|add_room_feature|dot||boolean|no_monsters}}&lt;br /&gt;
:Randomly selects a room generation function to be added to the map. ''no_monsters'' set to true excludes the possibility of a vault room being generated.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|handle_rooms|dot||boolean|no_monsters}}&lt;br /&gt;
:Generates up to seven special rooms on the map and restores walls that were otherwise removed as a result of the room generation.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|place_player|dot}}&lt;br /&gt;
:Adds to player to the map.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|roll_event|dot}}&lt;br /&gt;
:Randomly select a level event function to be added to the map.&lt;br /&gt;
----&lt;br /&gt;
;{{moddef|desc|reset|dot}}&lt;br /&gt;
:Clears all generation properties and hooks, and changes the map into one bordered with the level style's walls and otherwise filled with the level style's floors.&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Strategy:Ironman</id>
		<title>Strategy:Ironman</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Strategy:Ironman"/>
				<updated>2025-08-11T12:32:13Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
&lt;br /&gt;
==0.9.9.7==&lt;br /&gt;
&lt;br /&gt;
Ironman&lt;br /&gt;
&lt;br /&gt;
Ironman is a great trait to level up in--depending on what you want to do.&lt;br /&gt;
&lt;br /&gt;
As a &amp;quot;standalone&amp;quot; trait (i.e., a trait to level up in just 'cause), Ironman is a great fill-in if you don't want to get other more &amp;quot;important&amp;quot; traits first. &lt;br /&gt;
&lt;br /&gt;
This trait is also a great choice if you're really hurting in health, armor, and general resistances. Selecting Ironman won't give you &amp;quot;free health&amp;quot;, it simply boosts your max HP by 10 points (and actually boosts your current HP by 10 also). Because damage is dealt by calculating how much HP you have, and to an extent, the percentage of max HP you have, having a level or two in Ironman can really come in handy when the late-game enemies come out to play.&lt;br /&gt;
&lt;br /&gt;
Ironman will make you practically immortal against the former human/sergeant group (especially so when paired with a good armor and decent weapon).&lt;br /&gt;
&lt;br /&gt;
Last words of advice? Ironman is a great trait to level up in for a defensive build, or just a good trait to have after completing a Master build.&lt;br /&gt;
I would recommend leveling up in more savory traits such as Reloader, Son of a Bitch, Finesse, and so on before selecting this trait.&lt;br /&gt;
&lt;br /&gt;
[[User:GinDiamond|GinDiamond]] ([[User talk:GinDiamond|talk]]) 21:21, 14 October 2013 (CEST)&lt;br /&gt;
&lt;br /&gt;
One less-discussed factor about Ironman is that it increases the power of health kits and health levers, since these always heal you by a percentage of your maximum HP. It might not build to Badass (TaN does that), and it actually doesn't build towards anything but Survivalist for Marines, but it is also blocked by nothing, so it fits into any build. If you're a Marine, you get Badass access free anyway, and getting more health further increases the power of Badass, since your boosted maximum is also increased. Even if Badass is blocked by your Mastery, Ironman isn't, so it can toughen you up a great deal. On Ao100 or Ao666, Ironman is invaluable, probably even moreso than offensive traits once you finish your mastery, since later enemies have a high chance of instakilling you without it, and since it increases the power of health packs, it can push your limited resources farther.&lt;br /&gt;
&lt;br /&gt;
Since it does build towards Survivalist, it should be noted that Survivalist is probably the best General Mastery of all, since it makes you as tough as a goddamned tank. It might not be as fun as other masteries, but it's an ironclad insurance policy. More offense might help you win more fights, but more health will help you win the game.&lt;br /&gt;
&lt;br /&gt;
[[User:Vid-szhite|Vid-szhite]] ([[User talk:Vid-szhite|talk]]) 06:38, 3 February 2017 (UTC)&lt;br /&gt;
&lt;br /&gt;
Ironman is a filler trait through and through; 10 extra max HP is certainly not a bad thing to have (usually, we'll touch on that in a bit), but simply 10 extra HP isn't going to be doing all that much to win you the game in the way other traits will. Strictly defensive-based traits are already inherently flawed, as often for them to have any effect relies on bad play; there will certainly be situations where damage is unavoidable and even the best players will inevitably make mistakes that get them hit, but just playing better will do a lot to reduce the damage you take, and so traits that better facilitate good play thus have inherent value over those that rely on getting hit to have any effect. When it comes to improving your survivability, [[Strategy:Hellrunner|Hellrunner]] will often be the premier choice, as the increased movement speed and [[dodging]] rate will allow you to avoid hits you would have taken without it, while nothing reduces damage more than avoiding getting hit in the first place. Then Hellrunner is also not strictly a defensive trait, as it very much improves your offensive ability when you can better outmaneuver or approach enemies, and has other general utilities that taking less time per move grants. Another thing is that a good offense making a good defense is very much true in DRL; if you can kill enemies before they get the chance to attack you, you'll take no damage at all (i.e. the reason why [[Strategy:Angel of Max Carnage|Angel of Max Carnage]] is widely considered to be easier than the standard game, despite enemies hitting so brutally hard in it). As such, investing in DPS-boosting traits like [[Strategy:Finesse|Finesse]] and the various damage-boosting traits will very much keep you alive better than more max HP will. [[Strategy:Intuition|Intuition]] is another trait that will do a lot more to keep you alive; knowing where enemies are outside your vision will let you avoid stumbling into a bad situation in the first place, and knowing where powerups are will let you know where to beeline to if you need healing or the power of [[Invulnerability]]/[[berserk]] to fight a strong group of enemies. So overall, Ironman should generally only be picked after you already exhausted investing into pertinent traits and the only other remaining traits don't benefit your build at all (such as [[Strategy:Son of a Gun|Son of a Gun]] when you're not using [[pistol]]s).&lt;br /&gt;
&lt;br /&gt;
One more consideration with Ironman if you do want a defensive-boosting trait, is whether to choose it or [[Strategy:Tough as Nails|Tough as Nails]], assuming your master trait blocks neither, whether as an endgame filler trait or because you are actively trying to run an extreme tanking build that isn't Survivalist (which has both required for it). Ironman has a slight edge in normal circumstances, due to it giving you a slightly wider margin of error against highly-damaging hits, not having its effect reduced by half against [[plasma]] attacks like TaN does, and netting you more effective HP from percentage-based health sources as covered prior. However, if you got very good [[armor]] with strong enough [[resistance]]s to reduce damage to 5 or less, you will increasingly improve your effective survivability by increasing your innate [[protection]] rather than your max HP (with a [[Scout]] or [[Technician]], reducing 5 damage to 4 will make them go from dying in 10 hits to 13 while 10 extra HP makes them take 12 hits; reducing 4 damage to 3 makes them go from dying in 13 hits to 17 while Iro makes them take 15 hits; reducing 3 damage to 2 makes them go from dying in 17 hits to 25 while Iro makes them take 20 hits; reducing 2 damage to 1 makes them go from dying in 25 hits to 50 while Iron makes then take 30 hits). Additionally, if you got [[Strategy:Berserker|Berserker]], TaN is clearly better to invest in if it's not blocked; aside from the +60% resistance to all damage given by berserk letting you often reduce damage to that aforementioned 5 or less threshold even without particularly good armor, increasing your max HP will actually nerf the ability for Berserker to activate off of very strong hits that deal a third or more of your max HP in damage. Considering Berserker kicking in this way will apply the resistances of berserk before the damage is calculated for those nasty hits and thus drastically reduce their damage, investing in Ironman can actually substantially worsen your survivability in these cases (10 extra HP is doing shit with mitigating the 20 damage of an [[Arch-vile]] zap, whereas Berserker activating will reduce it to a much less harsh 8 damage ''before'' your own armor is applied). Additionally, Scouts and Technicians with their base 50 max HP can rather easily intentionally activate Berserker at any time by just blowing up rockets in their face, and [[Marine]]s can still at least get free berserk by letting an Arch-vile zap them or by blowing up a napalm [[barrel]] in their face, while investing in Ironman eliminates this ability (investing in Iro just once as a Marine, or twice as a Scout/Technician, will mean even an Arch-vile zap will no longer be able to activate Berserker). So considering that, if you have Berserker, you likely won't want to invest in Ironman even after you fully invested in all other useful traits. [[User:Omega Tyrant|Omega Tyrant]] ([[User talk:Omega Tyrant|talk]]) 18:30, 21 July 2023 (UTC)&lt;br /&gt;
&lt;br /&gt;
==0.9.9.8==&lt;br /&gt;
Ironman has been buffed in 0.9.9.8 in two ways.&lt;br /&gt;
&lt;br /&gt;
The first buff is that Berserker's activation from you getting hit is now based on nominal max HP, which means increasing your max HP from Ironman no longer hinders you from reaping the defensive benefits from Berserker (i.e. if you max out Ironman, attacks will still just need to deal one-third of 50 HP to activate Berserker rather than one-third of 100 HP). As such, if you're a melee build wanting easy Berserker procs from face rockets and the [[VMR]], or otherwise took Berserker for extra defensive insurance from very strong hits (as the resistances granted by berserk are still applied before damage is calculated), you can now take Ironman for extra durability and get the best of both worlds.&lt;br /&gt;
&lt;br /&gt;
The second buff is that each level of Ironman now cumulatively gives you +10% inherent resistances to [[bullet]], [[shrapnel]], and [[melee]] damage. Aside from giving extra defensive utility and more value to take as an endgame filler trait (with multiple levels of Ironman combining nicely with armors that have strong energy resistances to bolster any lack of physical resistances they may have), there are these particular scenarios where this buff especially helps:&lt;br /&gt;
&lt;br /&gt;
*Taking Ironman early or even as your first trait has more merit, when you're fighting predominantly Formers and melee enemies during the early game. Even just a single level for only 10% physical resistances is enough to reduce damage by 1 from [[Former human]]s over half the time, from each bullet of a [[Former captain]] burst a third of the time, always from a [[Lost soul]] charge and [[Demon]] bite, and nearly always from a [[Former sergeant]]'s [[shotgun]] blast (or even save you 2 damage if you take a high damage roll from close range). That is on top of the increased HP you get, and like all resistances, it gets applied before your armor, so it can seriously extend survival in the early game; for example a Demon bite does 7 damage on average, killing a Scout/Technician in 8 hits, while Green Armor will reduce it to 6 damage and extend survival by only a single hit, whereas with Ironman's 10% melee resistance + Green Armor reducing it to 5 damage while you now have 60 HP, it takes 12 Demon bites to kill you.&lt;br /&gt;
&lt;br /&gt;
*Ironman is obviously much more lucrative for melee builds and melee-locked challenges, where lots of melee damage is unavoidable, and as demonstrated in the prior point, even just one level makes a substantial difference with increasing your hit-taking ability against enemies with mid tier melee attacks (that is unless you're running [[Strategy:Vampyre|Vampyre]] of course, where it being allowed the buffed Ironman proved to be near-IDDQD and so it's now the only mastery that blocks Ironman), while each additional 10% from successive levels of Ironman will reduce another point of damage from high tier melee attacks that deal at least 9 damage (or even 2 damage in the case of certain bosses and nightmare enemies with especially powerful melee attacks). Additionally, the resistances granted by Ironman get applied in damage calculation before your armor is factored, which means unlike Tough as Nails, Ironman ''does'' reduce damage your armor takes, and so your armors will also be lasting longer in melee combat (especially valuable as armor gets worn down so fast when you're fighting predominantly in melee).&lt;br /&gt;
&lt;br /&gt;
*If you're trying to clear [[Unholy Cathedral]] with a build that has no [[Strategy:Brute|Brute]] investment nor the movement + attacking speed to repeatedly hit the [[Angel of Death]] without retaliation, a level or two into Ironman in conjunction with an armor that has strong melee resistance can push you into the range to reduce the AoD's attacks to 1 damage and thus still beat him in hand-to-hand combat (for example, +20% melee resistance from two levels of Iro combined with the 40% melee resistance and 6 protection of a P-modded [[Ballistic armor|Ballistic]] [[Red armor]] will be enough to reduce all the AoD's attacks to 1 damage).&lt;br /&gt;
&lt;br /&gt;
Overall, Ironman is still mostly a filler trait for all the reasons I laid out prior, at the end of the day ramping up your offense and speed still reigns supreme in DRL over what is still a purely defensive trait, but now it can benefit you to pick it sooner than endgame filler, and otherwise there's no longer reason to actively avoid picking it. [[User:Omega Tyrant|Omega Tyrant]] ([[User talk:Omega Tyrant|talk]]) 04:31, 20 July 2024 (UTC)&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/VMR</id>
		<title>VMR</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/VMR"/>
				<updated>2025-08-11T12:32:03Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;VMR is a slang term in the DRL community used to quickly refer to the following three enemies:&lt;br /&gt;
&lt;br /&gt;
*V = [[Arch-vile]]s&lt;br /&gt;
*M = [[Mancubi]]&lt;br /&gt;
*R = [[Revenant]]s&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Strategy:Hellrunner</id>
		<title>Strategy:Hellrunner</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Strategy:Hellrunner"/>
				<updated>2025-08-11T12:31:55Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
&lt;br /&gt;
==0.9.9.7==&lt;br /&gt;
&lt;br /&gt;
Hellrunner is an amazing trait that new players don't even realize the value of, but veterans eventually learn all the reasons to love. One of the biggest and most underrated reasons is that with two levels of Hellrunner, you're faster than [[Demon|Demons]] even while tired or cautious, but without Hellrunner, you have to start [[Tactics|Running]] and then expend almost all your moves in order to gain even one tile of space, and on UV, you better not be wearing armor or you're too slow to even do that while running. Hellrunner 2 makes Running speed your ''base'' speed, and makes you even better at dodging.&lt;br /&gt;
&lt;br /&gt;
Another big reason to love it is that without its increase to dodge chance, you might as well not even bother trying to use the [[Dodging]] mechanic. Without any Hellrunner levels, dodging is essentially a coin flip against any fireball, and it's basically useless against Formers. With just Hellrunner 2 though, not even [[Dodgemaster]], your base chance to dodge fireballs jumps up to 80% before distance is factored in. That's a big difference! With Dodgemaster added in, you can dodge even the first bullet fired at you for free, and once you can actually use the dodging mechanic, getting caught out in the open surrounded by monsters is no longer a surefire death sentence. You can actually use dodging while zig-zag running to safety and the monsters chasing you will kill each other with attacks meant for you. Dodging is also one of the only ways to defeat the Cyberdemon on higher difficulty.&lt;br /&gt;
&lt;br /&gt;
Being able to actually run away from things without chugging all your medkits or gambling on a phase device will let you survive so many difficult moments it's not even funny. I'll let Omega Tyrant go into detail about that though.&lt;br /&gt;
&lt;br /&gt;
[[User:Vid-szhite|Ya Girl Juniper]] ([[User talk:Vid-szhite|talk]]) 11:48, 28 May 2023 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hellrunner increases your base movement speed by 15% for each level you take in it, as well as gives you an additional 15% bonus to your dodging rate. You can take up to 2 levels in Hellrunner normally for +30% movement speed and dodging rate, while upon hitting level 12 you can take a third level, for a maximum increase of +45%.&lt;br /&gt;
&lt;br /&gt;
Movement speed is extremely important in DRL, for offensive, defensive, and general purposes. The better you're able to outmaneuver your enemies, the more favorable position you can manipulate them into and better confront them on your terms. The faster you can move and better you can dodge, the easier it will be to approach and fight enemies in the open. When needing to escape from a bad situation like being surrounded by enemies, nothing else will help you as much as movement speed and your dodging rate. When it comes to damage reduction, nothing reduces damage more than avoiding taking damage in the first place, so levels in Hellrunner can do a better job at keeping you alive than  investment in [[Tough as Nails]] and [[Ironman]], especially when boosting your movement and dodging through equipment is harder than simply getting better protecting armor. Then you can run into [[level event]]s like acid/lava floods, armed nukes, and deadly air, where being able to escape/finish the level as soon as possible is imperative to avoid dying, and the less time you spend with each move, the greater leeway you get in being able to complete and thus survive these levels. Then when you're stair diving, the better you're able to evade enemies the easier and quicker you'll be able to get to the stairs. Another thing is when your health is boosted above 100% and you don't have the necessary levels of [[Badass]]  to retain it, its decay rate is based on time (5.0 seconds to be exact). So the faster you move, the more actions you get to retain the boosted health, and if you gather up any remaining health globes/[[Supercharge]]s/[[Megasphere]]s at the end of the level, the more boosted health you'll get to carry with you to the next level, especially if those powerups were spreadout and/or located far away from the stairs.&lt;br /&gt;
&lt;br /&gt;
Two levels in Hellrunner will additionally give you access to [[Dodgemaster]], which allows you to dodge the first projectile thrown at you between moves with a 100% dodging rate, a very handy trait to reduce the damage you sustain farther, as well as give you a free win against the [[Cyberdemon]] and make [[John Carmack]]'s rockets a nonissue. &lt;br /&gt;
&lt;br /&gt;
So Hellrunner by itself is a very helpful trait to invest in regardless of your build, and is probably the most helpful basic trait independent of other factors. Fortunately many master traits have Hellrunner investment as a prerequisite; [[Blademaster]], [[Malicious Blades]], [[Gun Kata]], [[Shottyhead]], [[Fireangel]], and [[Gunrunner]]. You'll never feel constricted or as if you could have gotten something more useful when having to take Hellrunner to get your master. Quite a few masters block Hellrunner however; [[Vampyre]], [[Bullet Dance]], [[Army of the Dead]], and [[Survivalist]]. Vampyre though is the only master trait of those considered to be a worthwhile pick over their competitors, and not being able to get Hellrunner plays a part in those other masters being considered underwhelming.&lt;br /&gt;
&lt;br /&gt;
If your master doesn't require Hellrunner, Hellrunner is a great trait to invest in after you get your master for any build that doesn't block it, and it will often be the most useful trait to invest in after your master, with [[Finesse]], [[Whizkid]] and [[Intuition]] being its only strong competition. If your master doesn't require it but doesn't block it, it may even be a decent idea to take a level in Hellrunner before getting your master, as delaying your master a level to get Hellrunner could mean the difference between death and being able to live long enough to get your master at all. [[User:Omega Tyrant|Omega Tyrant]] ([[User talk:Omega Tyrant|talk]]) 20:04, 28 April 2017 (UTC)&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Strategy:Unholy_Cathedral</id>
		<title>Strategy:Unholy Cathedral</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Strategy:Unholy_Cathedral"/>
				<updated>2025-08-11T12:31:46Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
Unholy Cathedral is a special level which has a gimmick of melee-exclusivity. The level only features melee enemies, including a melee-only boss with ridiculous stats, and any guns will not fire if you attempt to, keeping you restricted to only melee attacks outside a few exceptions that will be covered later. Killing the [[Angel of Death]], the boss of the level, will reward you with the [[Longinus Spear]], an extremely powerful melee weapon that far exceeds any modded Chainsaw. Beat him on at least Hurt Me Plenty difficulty while carrying a 100% killrate up to that point, you'll instead be rewarded with the even more powerful [[Azrael's Scythe]]. Then if you beat him on Nightmare difficulty, while having beaten [[Hell's Arena]] earlier in the run without taking damage, you'll instead be rewarded with the [[Dragonslayer]].&lt;br /&gt;
&lt;br /&gt;
If you're a melee build, or at least have some investment in [[Brute]], [[Berserker]], and a [[Chainsaw]], this level will be ridiculously simple. A horde of [[Lost soul]]s and [[Demon]]s are little threat and you can just run in, get berserked, and steamroll over them, while then run up to the Angel of Death and mash click until he dies. The ease of difficulty and the amazing melee weapon you get for beating this level makes it a mandatory stop for melee builds, and upon beating it the rest of the game will become a cakewalk, especially if you fulfilled the conditions to get Azrael's Scythe or the Dragonslayer. &lt;br /&gt;
&lt;br /&gt;
If you're not a melee build while lacking Brute and Berserker, beating this level becomes a much more arduous task you will need proper preparation for, and you should normally skip it unless you're trying to achieve a Conqueror run (or really want that melee Artifact, in which case you probably would have invested in Brute and Berserker in the first place). The simplest way will be to find and carry with you a [[Thermonuclear bomb]] or some other means to nuke a level, and then find an [[Invulnerability Globe]] on dlevel 17, where you can then go into the Unholy Cathedral invulnerable and nuke the level (which will even still reward you the Artifact). This method however obviously relies on a great deal of luck, and shouldn't be relied on as your main plan, being reserved for non-melee builds who didn't intend to enter the Cathedral but happened upon these circumstances that allowed them to nuke it for some extra EXP.&lt;br /&gt;
&lt;br /&gt;
When it comes to beating the level normally, it all revolves around being able to kill the Angel of Death. With an unmodified Chainsaw and no trait investment you can usually one-shot the Lost souls, while being able to chokehold them in the doorway to their room so they can't surround you. Then with the Demons, you can lure them outside into the lava that will quickly make short work of them. So that just leaves overcoming the Angel of Death in melee combat, whose health will be 290/340/410/500 depending on difficulty, while he boasts an incredible 10 armor to substantially soften your blows and make him an even greater tank than [[John Carmack]]. In addition, he's extremely fast at 150% speed, and his melee attack deals between 16-18 damage, enough to three-four shot any class without [[Ironman]] investment and any armor, while with a [[Red armor]] you'll only be able to take one more hit. So how do you beat him without Brute and Berserker, when you can't possibly hope to outdamage him in melee?&lt;br /&gt;
&lt;br /&gt;
==Weaponry==&lt;br /&gt;
So without relying on luck to nuke the level, the thing you're going to need most is a [[Piercing blade|Piercing Chainsaw]]. With his armor, an unmodified Chainsaw will deal 1-14 damage, with several hits doing only 1 damage while averaging less than 5 against him, and bulk modded it will just raise it to a paltry 1-20 while the average will still be below ten damage. With a Piercing Chainsaw, you completely ignore his armor, and your attacks will be dealing 4-28 damage while averaging around 15, a tremendous improvement in your damage output against the Angel of Death while you're not sacrificing that much mods from your other more valuable equipment. A [[Double chainsaw]] and [[Ripper]] will offer even greater damage output despite no piercing effect, but with no Brute nor [[Eagle Eye]] investment, you'll be hitting with the Double chainsaw only a fourth of the time and not even a tenth of a time with the Ripper, which with their heavy mod investment, makes them horribly impractical for the purpose of beating the AoD with a non-melee build. &lt;br /&gt;
&lt;br /&gt;
If you happen to find a [[Butcher's Cleaver]], it will deal 1-20 damage with an average below 10, so it would still be significantly inferior to the Piercing Chainsaw, and its Blademaster effect does nothing in 1-on-1 combat. If you somehow found the [[Dragonslayer]] before the Cathedral and were able to pick it up, then you can just run in and beat this level with no problem at all regardless of your build.&lt;br /&gt;
&lt;br /&gt;
==Armor==&lt;br /&gt;
===Standard armors===&lt;br /&gt;
The other necessary piece of equipment is an armor with melee resistance, as a standalone Red armor barely helps as covered earlier, and a [[Power mod]] to it ''might'' let you just take one more hit. When it comes to the standard armors, none of them feature melee resistance at base, so the easiest reliable option is the [[Ballistic armor]] assembly, which gives any armor it's applied to an additional 30% melee resistance. Applied to a Red armor, you'll be taking 7-8 damage, so an unboosted Scout/Technician will be able to take 7 hits from the Angel of Death and a Marine will take 8-9 hits, a big improvement when you'll be able to live about twice as long against him between [[Large medkit]]s. However even on HNTR difficulty with the Piercing chainsaw, your life will be getting drained a lot faster than his, when it will take you about 20 hits to kill him assuming all your hits connect (which they won't without Brute/Eagle Eye). Plus your Ballistic Red armor will get damaged and lose half of its resistance around the time you need your first medkit, while the AoD will still have plenty of health left. So the Piercing chainsaw + Ballistic Red armor combo alone won't be viable without a spare, a lot of Large medkits, and maybe copious investment in [[Tough as nails]], and you'll definitely need something more on UV/Nightmare.&lt;br /&gt;
&lt;br /&gt;
The other remotely viable standard option is to make the [[Power armor]] assembly with Red armor. It gives it a 25% melee resistance and an additional point of protection, which too will reduce his damage output to 7-8, so again it's not that good an option. However the armor regenerates and completely removes the movespeed penalty, so it won't be difficult to run away from the AoD while the armor regenerates before confronting him again between medkit uses. You will still need a lot of medkits, but you won't need multiple armors. Power armor requires a coveted [[Nano mod]], and it's very unadvised to make Power armor just for the AoD if you get a Nano mod as it's only a bit better over Ballistic Red armor, so it should only be a really desperate last resort option unless you're making Power Red armor already for general usage.&lt;br /&gt;
&lt;br /&gt;
So preferably you will need some luck on finding an Exotic or Unique armor, but fortunately there are many of them that have melee resistance and you have a decent chance of finding at least one of them before the Unholy Cathedral.&lt;br /&gt;
&lt;br /&gt;
===Exotic/Unique armors===&lt;br /&gt;
Among Exotics, there's the [[Ballistic shield]], which with its 95% melee resistance, will reduce any melee attack in the game to 1 damage. Plus being a shield, its resistances won't worsen when durability drops below 50%, so you'll effectively get 100 hits you can take against the Angel of Death with it on, all for 1 damage each (assuming you didn't let it lose durability prior to the Lost souls and Demons earlier in the level, and kept it fresh for the Cathedral), which even on Nightmare will give you way more than enough durability to beat him with just a Piercing chainsaw and no melee investment. &lt;br /&gt;
&lt;br /&gt;
Outside shields, the best Exotic armor for this will be the [[Gothic armor]]. It carries a 50% melee resistance alongside a 6 protection rating, so unmodified the AoD will only be dealing 2-3 damage, allowing you to go over 20 hits without needing to pop a medkit, and it boasts 200% durability, so it will take a really long time before the AoD will be able to damage it. Even on Nightmare you will only need about 1 or 2 medkits, and if you apply a Power mod to it or have TaN investment, he'll only be hitting you for 1 damage, giving you a free win. The nigh-immobility of the Gothic armor is also a nonissue, when you will just be standing there trading blows and when it protects so well that the AoD getting a couple extra hits during medkit usage won't be an issue.&lt;br /&gt;
&lt;br /&gt;
The next best Exotic will be [[Duelist armor]]. It too carries a 50% melee resistance, but with only a 2 protection value. Wearing it at base the AoD will deal 6-7 damage, not much of an improvement over Ballistic Red armor as you might just be able to take one more hit. However with just a Power mod applied, he will be doing 4-5 damage, and now a Scout/Technician at base will take 10-13 hits to kill and a Marine will take 12-15, giving you quite a bit more hits you can take between medkits. It additionally boosts your speed, so if you at least have [[Tactical boots]], you'll be able to run away to pop medkits regardless of [[Hellrunner]] boosts. Above HNTR you'll probably need to apply a [[Bulk mod]] in addition to the Power mod for it to survive more than one medkit round without being damaged if you don't have TaN investment, or otherwise sacrifice its usage for general play outside the Cathedral and turn it Ballistic. A Ballistic Duelist armor will have a massive 80% melee resistance, reducing all hits from the AoD to 1 damage, but that -30% fire resistance means you can no longer wear the Duelist armor when [[VMR]] are around.&lt;br /&gt;
&lt;br /&gt;
Then there's the [[Ballistic vest]], which also carries 50% melee resistance, but only 1 point of protection, so you'll take 1 more point of damage with it than you would with the Duelist; even if you use the Ballistic armor assembly on it to increase its resistance to 80%, you'll still take 2 damage unless you have TaN or were able to make it after [[Whizkid]] 2 and thus be able to apply a Power mod to it. If you find one, you should definitely use that assembly on it if you have no plans to turn it [[Cerberus armor|Cerberus]] as it's not that useful outside the Cathedral, but on UV and Nightmare you may need a bit more to win here if you don't get TaN or Whizkid 2 + a Power mod to reduce the AoD's damage to 1 with it.&lt;br /&gt;
&lt;br /&gt;
[[Phaseshift armor]] has a base 30% melee resistance alongside 2 protection, so you'll be taking 9-10 damage at base, which as you can see previously clearly isn't enough on its own. Turning it Ballistic to get 60% melee resistance will reduce the AoD's damage down to 4-5, which as established previously isn't quite enough above HNTR on its own unless you had [[Whizkid]] 2 and can apply a Power/Bulk mod or have TaN, while turning it Ballistic will lessen its great general usage by giving it a fire vulnerability. Its +25% movement speed at base though, that can be improved to +40% with an [[Agility mod]], makes it ideal for some certain non-conventional strats that will be elaborated on later.&lt;br /&gt;
&lt;br /&gt;
Then there's the [[Medical armor]], which carries 20% melee resistance with 2 protection, obviously not enough. Turning it Ballistic will make it equivalent to the base Duelist armor, making it ok as a spare or otherwise with copious support. If you do use it, remember it starts regenerating your HP back up to 25% when it dips below that mark at the cost of its durability, which is a rather detrimental effect when you want the armor to keeps its protection as long as possible while you can heal instantly anyway with Large medkits, so you might want to use your medkits a bit early if you do have the armor on unless your medkit supply is near diminished.&lt;br /&gt;
&lt;br /&gt;
Among Uniques, there's the [[Shielded Armor]], which with its 90% melee resistance and 2 protection to reduce the AoD's hits to 1 damage, in conjunction with its infinite durability, is pretty much an &amp;quot;I win&amp;quot; button for the Cathedral as long as you have the Piercing chainsaw. Then there's the [[Cybernetic Armor]], which has 50% melee resistance and 7 protection to reduce the AoD's hits to 1-2 damage, but with it being cursed and it having no regeneration, putting it on just for the Cathedral is obviously a bad idea that will cripple you for the rest of your run. If you're a Technician though who put it on and assembled it to [[Nanofiber skin armor]] or [[Cybernano armor]], then you'll be taking only 1 damage while having regenerating armor, giving you a free win here.&lt;br /&gt;
&lt;br /&gt;
==Other items of interest==&lt;br /&gt;
When it comes to items besides the obvious medkits you can use to help, the most useful by far is the [[Hatred skull]], as it gives builds without Berserker the ability to get berserked on the level. Even with just Red armor and the Piercing chainsaw the level becomes easily doable for non-melee builds on about any difficulty, and a free win with any of the melee-resistant armor, provided they can get enough turns of berserk. That is the tricky part, as your only source of corpses in the Unholy Cathedral are the Demons, where killing them via lava will obviously leave no corpse, while they'll leave no corpse if you kill them in a doorway, and if you destroy the door to avoid that but kill them in the created chokehold to avoid getting surrounded, their corpses will replace each other and thus potentially leave you with as little as a single corpse. So you'll have to kill the Demons yourself instead of via lava, avoid killing them in a doorway, and leave their corpses scattered, in order to get as much turns of Berserk as you can. The good news is you don't need that many corpses even on Nightmare, so as a rule of thumb you can kill half the demons chokeholded through the doorway (5 on HNTR and HMP, 8 on UV and Nightmare), and then lure the rest outside and avoid killing them on top of each other. You might have to expend a medkit or two, but it will be worth it to get berserked against the AoD, especially if you don't have a good melee-resistant armor. A Hatred skull isn't guaranteed, but you have a good chance of getting one if you killed the [[Agony elemental]] in [[City of Skulls]]/[[Abyssal Plains]].&lt;br /&gt;
&lt;br /&gt;
When it comes to the other skulls, the [[Blood skull]] should unquestionably be saved for [[The Mortuary]]/[[Limbo]], when you'll need ten corpses to get as much healing as a Large medkit, while you'll probably end up losing more than that health trying to kill the Demons that separated from each other. The [[Fire skull]] is a way to deal damage to the AoD outside melee, and each explosion from it can deal over 20 damage to him. With the explosions being able to gib corpses before they explode however, you'll need to kill the Demons really separated from each other to get significant damage on the AoD, so it's definitely not a reliable tool to beating him and it's better saving it for The Mortuary/Limbo. It can come handy though as a last resort to deal a much-needed big punch, when your armor and medkits are depleted with the AoD still not near death. &lt;br /&gt;
&lt;br /&gt;
When it comes to other non-melee ways you can damage the the AoD, there's the [[Arena Master's Staff]], but with it dealing only 1 damage to the AoD while exhausting you, using it for that purpose is a joke. If you have the [[Subtle Knife]], its altfire can be used to deal 5 damage to the AoD, but with it exhausting you and permanently draining 2 HP from your max health, this too is never going to be worth it. The [[Shockwave pack]] will deal around 40-50 damage, a lot more damage than a non-melee build could ever hope to do in a single hit, and taking a good chunk out of the AoD's health. You might want to save a Shockwave pack for a perilous surrounded situation or The Mortuary/Limbo, but it could definitely be the extra push needed to win here if you didn't get good enough melee armor. Then there's the [[Hellwave Pack]], which will deal twice as much damage as the Shockwave pack. Again you might want to save it, but that could be a really big help here if you didn't get a Hatred skull and your armor is lacking.&lt;br /&gt;
&lt;br /&gt;
==Non-conventional strats==&lt;br /&gt;
So you're a non-melee build where some combination of factors prevents you from realistically beating the Angel of Death in straightup combat, or simply you don't want to expend all these resources and effort to beat him while still wanting that Conqueror medal, you may be wondering if there's any way to just cheese it if you weren't able to nuke the level. Well one more way to damage the AoD without going into melee range is to a throw a [[Combat knife]] at him. You may be wondering how a thrown knife that will deal only 1 damage all of the time with no Brute, miss half the time without Eagle Eye, and you'll have to pick back up after each throw, would ever be remotely useful for beating the AoD. Well if you can get your movement speed faster than .67 seconds without having to activate [[Run]] (Phaseshift and Duelist armor will be very helpful to passing this benchmark), you can throw the knife a safe distance away, outmaneuver the AoD, pick the knife back up, throw it again, and repeat until the AoD dies, without him ever being able to touch you. Of course with the AoD having 290 health at minimum on the easiest difficulty you can fight him and as high as 500 on Nightmare, it's going to take a '''''loooooooooooooonnnnnnnnnnnggggggggggggggggggg''''' time until he dies, compounded farther by all the time you're going to have to spend lapping him to pick the knife back up inbetween throws. If you found and kept the [[Mjollnir]], another melee weapon you can throw, you can do this strat with it instead of the Combat knife, and since it doesn't leave your hands upon throwing it while some of it hits will deal a little over 1 damage to the AoD without any Brute, this strat will be a lot faster using the Mjollnir, but will still take a very long time.&lt;br /&gt;
&lt;br /&gt;
The other option is to get both your movement and attacking speed faster than the AoD (faster than .67 seconds to be precise), where you will then be able to run away while being able to hit the AoD between its moves without retaliation (reaching that attack speed benchmark with a Scout will just require two levels of Finesse, but a Marine and Technician will need all three levels of Finesse, or two levels of Finesse and a Technical mod on their Chainsaw). If you're fast enough to do this method, your equipment and resources don't matter, and it won't take ridiculously long to kill the AoD as long as you have at least a Chainsaw (though making it piercing and/or having at least one level in Brute/Eagle Eye so you don't miss so often will speed the process up a lot). However to implement this strat, you need to understand how [[Time]] works in DRL, and have an acute enough sense of timing of yours and the AoD's movement to be able to time your hits correctly inbetween the AoD's moves, otherwise you'll just get mauled as you attack. Once you learn the trick, it's not difficult to do (get three tiles away from the AoD, wait a turn, and if he moves two tiles, you'll be able to get a hit in without him hitting back), but this is still something your average player will probably not be comfortable trying, and the margin of error isn't forgiving when any mistake will result in you taking a lot of damage if you don't have one of the aforementioned very strong melee-resistant armors (which considering how slow most of them are, you probably won't be able to use for this strat).&lt;br /&gt;
&lt;br /&gt;
Now what if you're a non-melee build who doesn't have good enough equipment, can't nuke the level, and aren't fast nor patient enough to do those non-conventional strats? Well you're shit out of luck then, the Unholy Cathedral is effectively unwinnable and you'll need to skip it or die. [[User:Omega Tyrant|Omega Tyrant]] ([[User talk:Omega Tyrant|talk]]) 03:17, 2 May 2017 (UTC)&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Strategy:Acid_Spitter</id>
		<title>Strategy:Acid Spitter</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Strategy:Acid_Spitter"/>
				<updated>2025-08-11T12:31:38Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
&lt;br /&gt;
At first glance this looks like it could be an incredible weapon; 10d10 power is absolutely ridiculous, it can possibly one shot almost any normal enemy in the game and its average damage of 55 exceeds the maximum damage output of any rocket launcher while it carries a respectably large explosion radius of 3 to demolish hordes of enemies. The acid tiles it leaves behind in its explosion radius will additionally damage enemies farther, and potentially trap them to die if they're left surrounded by acid. It looks like it could be a [[Napalm launcher]] on steroids that just leaves behind acid instead of lava, but if there's a posterchild for awesomely impractical weapons in DRL, the Acid Launcher may take that title.&lt;br /&gt;
&lt;br /&gt;
The critical problem with the weapon is how its ammo and reloading works. The Acid Spitter doesn't utilize conventional ammo, instead it actually uses acid. How it works is it has a clip of 10 that is expended entirely when it's shot, so you only get one shot with this weapon between reloads. Then to restore its ammo you have to be on top of an acid tile and then hit the reload button, where the acid is then absorbed into the Spitter. Each absorbed acid tile counts for 1 point of ammo, so you'll need to walk over and manually absorb 10 acid tiles before the Spitter is fully reloaded and able to be fired again. First this means unless you have a pair of boots that make you immune to acid this weapon is effectively unusable, as you'll need radsuits or excess sources of healing to reload the Spiiter, effectively meaning you'll practically only get to fire this weapon once or twice per level on average. And then even if you do have acid-immune boots, it'll effectively take you 20 actions to fully reload the Spitter; besides that being extremely tedious on its own, you'll typically only be able to fire once when enemies are onscreen, as it doesn't matter how fast your movement and reloading is you're going to be a sitting duck if you actually try to reload this thing with enemies in sight. You could possibly run away to reload it elsewhere, but unless you're in later Phobos or earlier Deimos you probably will lack an adequate source of acid to reload the Spiiter and will be relying on the acid it leaves around to reload, which immediately after firing will be right where the enemies are.&lt;br /&gt;
&lt;br /&gt;
For actual combat purposes the Acid Spitter will be at best a very supplemental situational weapon; its best use will be if you have [[Juggler]], where you can fire it at a group of enemies to substantially weaken them and leave acid around them to inhibit their movement or trap them, while you then utilize Juggler to instantly switch to your primary weapons to finish them off. The one good caveat that comes from its unusual mechanics and ammo is that you won't have to devote any inventory space to ammo for it, and since its shots will usually leave behind enough acid to reload it, it will be self-sufficient without having to rely on other sources of acid spawning. So besides providing a big one-time punch to enemy hordes, it could also save you some ammo too. However, you're probably better off carrying another stack of ammo over keeping the Acid Spitter around, which will usually obsolete its potential ammo saving capabilities unless you're strapped for ammo when you find the Spitter. And of course, this all assumes you have acid-immune boots; if you don't have any and don't plan on making [[Cerberus boots]], absolutely do not bother with the Spitter if you find it.&lt;br /&gt;
&lt;br /&gt;
For one final note, if you are using the Acid Spitter, remember that [[Baron]]s have a massive 50% acid [[resistance]], so they won't be damaged much by it and you can forget about any theoretical one shot kills on them. Despite their great acid resistance, they'll still not cross acid tiles, and if surrounded by acid they won't bother getting out, so you could still utilize the Spitter to inhibit or trap them. Just beware a Baron trapped in acid will take a very long time to die (they only take 1 damage from acid per action), and despite not being able to move, it will still fire at you when you're in sight, so don't dawdle around an acid-trapped Baron. [[User:Omega Tyrant|Omega Tyrant]] ([[User talk:Omega Tyrant|talk]]) 08:50, 28 October 2019 (UTC)&lt;br /&gt;
&lt;br /&gt;
For yet one more note, the Acid Spitter gives you a massive +75% acid resistance when equipped, but not when in your prepared slot. This mainly just serves to prevent you from accidentally instagibbing yourself with this weapon if you get caught in its explosion radius rather being something you can get real defensive utility from, as the only two enemies in the game with acid attacks, Barons and their boss variations in the [[Bruiser brother]]s, have the aforementioned 50% acid resistance that makes using this weapon against them laughably ineffectual (especially so for the Bruisers, as they don't take fluid damage and so you can't even attempt to trap them with acid). Melee builds however, can actually get utility from the Acid Spitter's bonus resistance if they have Juggler; while Juggler primarily exists for allowing instant weapon swapping, its other less utilized effect is allowing you to attack with a melee weapon in your prepared slot without having to swap to it. Normally this doesn't provide a real benefit, as you could have just instantly swapped to your prepared melee weapon anyway from Juggler, but the exception is here with the Acid Spitter, as this allows you to keep it equipped in the primary slot to get the +75% acid resistance while still being able to attack with a melee weapon. Considering how difficult it is to get armor with good acid resistance, this niche usecase can come handy to neuter the threat of Barons' acid balls if you're able to effectively exploit it (though they'll still hit you hard in melee if you don't have strong melee-resistant armor too). [[User:Omega Tyrant|Omega Tyrant]] ([[User talk:Omega Tyrant|talk]]) 07:55, 9 July 2024 (UTC)&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Strategy:Archangel_of_666</id>
		<title>Strategy:Archangel of 666</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Strategy:Archangel_of_666"/>
				<updated>2025-08-11T12:31:31Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
&lt;br /&gt;
This challenge is just [[Angel of 100]] on steroids, where instead of the game ending after 100 floors you'll now have 566 more on top of that. It still pretty much plays the same way so the information found in the [[Strategy:Angel of 100|strategy page for Angel of 100]] is fully applicable here, the main difference being that unless you're someone who doesn't value their time at all and actually finds enjoyment from continuing the same DRL run for 566 more floors, '''you are going to start stair diving at some point'''. To make the stair diving most efficient to clear the additional 566 levels of grind as fast as possible you will need to pick a Scout for your class, playing a Marine or Technician will just needlessly cost you hours of additional time in your stair diving and make this so much grindier.&lt;br /&gt;
&lt;br /&gt;
For some additional notes, the danger level used for level generation '''does''' stop rising after dlevel 100, so from that point forward there will be nothing new and levels cannot get anymore dangerous. If you want the [[Experience Cross]], this will be one of the only three realistic ways you can reach the max level of 25 to obtain it. This will additionally be the easiest way of the three methods to obtain it, as the other two require either playing Angel of 100 on [[Nightmare]] difficulty or combining [[Angel of Darkness]] with Angel of 100 in a Dual-Angel challenge. Then for the final note the [[Apostle]] does still spawn here on the final floor if you reach it with the [[Dragonslayer]] and [[Berserker Armor]] equipped. So if you want to kill him for the [[Apostle Insignia]] or for whatever reason, this will be the closest way you can guarantee it happening in a run without save scumming, as it still requires a lot of luck in Angel of 100, and an extreme amount of luck in the normal game whether you're relying on random drops or actually try for the guaranteed drops on Nightmare. As it is, each Unique can only spawn once in a game, so besides there being 565 more floors for the Dragonslayer and Berserker Armor to spawn in, other Uniques will be gradually taken out of the item generation pool as they spawn, gradually increasing the chances of you finding the DS and BA as you go on. If you're trying to do this and are stair diving, just pay attention to the level feeling at the start of each dlevel as it will notify you if a Unique has been spawned. If nothing, you can just head straight for the stairs, and if there is you can just seek it out, pick it up to take it out of the item generation pool, and keep going until you find the DS and BA. You can also run a few Ao666 games doing this to build your overall Unique collection for the Armorer [[badges]], where the gold badge requires finding all Exotics and Uniques, the platinum badge requires obtaining 1000 cumulative Exotics and Uniques total on your file, and the diamond badge requires you obtaining 3 of each Exotic and Unique on your file. There are 26 Uniques total, so you're essentially guaranteed to come across them all in 666 floors, so speedrunning a few Ao666 runs will be the fastest way to obtain all the Armorer badges and probably the easiest diamond badge. [[User:Omega Tyrant|Omega Tyrant]] ([[User talk:Omega Tyrant|talk]]) 07:10, 31 October 2019 (UTC)&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Strategy:Army_of_the_Dead</id>
		<title>Strategy:Army of the Dead</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Strategy:Army_of_the_Dead"/>
				<updated>2025-08-11T12:31:23Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
&lt;br /&gt;
When it comes to [[Shotgun Types|shotguns]], there are two primary weaknesses; shotguns have much worse DPS potential than other weapon types, and [[shrapnel]] [[damage]] gets doubly reduced by [[armor]], which not only compounds the aforementioned DPS issue, but also substantially hurts the ammo efficiency of shotguns when you start having to regularly fight enemies with 2 armor, such as [[Baron]]s, [[Former commando]]s, [[Arachnotron]]s, and the [[VMR]]. This can especially hurt later in the game, when [[shotgun shell]]s can become rather scarce, with them spawning less often and [[Former sergeant]]s stop spawning outside of [[monster group]]s, leading to shotgun builds possibly finding themselves short on shells in Hell. The latter problem can be addressed by the [[Marine]]'s shotgun mastery, Army of the Dead (MAD for short), which turns the damage type of all shrapnel weapons to piercing. This means instead of your shotguns' damage being doubly reduced by armor, they now completely ignore armor. So against all those aforementioned enemies with 2 armor, your shotguns will be dealing 4 more damage per hit, while against certain nightmare enemies and bosses, you can see an even greater damage increase. Put that way though, considering most of the time you're getting either just 2 or 4 extra damage per shotgun shot, you may be thinking this sounds underwhelming compared to some of the crazy stuff and unique utilities other masteries can do, when you'll ultimately just be saving a shell or two on those bigger baddies, and well... you would be right. But still it's a nice perk to have, so what's the catch? Well, there's some really big catches, that makes Army of the Dead one of the worst masteries in the game.&lt;br /&gt;
&lt;br /&gt;
==The costs of Army of the Dead==&lt;br /&gt;
So what makes Army of the Dead so bad? A crucial part of masteries is that each of them will block you out from being able to pick certain traits. For most masteries, there may be a trait or two you may have wanted, but for the most part the tradeoff is well worth it. When it comes to Army of the Dead, you get blocked... [[Strategy:Eagle Eye|Eagle Eye]], [[Strategy:Hellrunner|Hellrunner]], and [[Strategy:Finesse|Finesse]]. ''Oh damn''.....&lt;br /&gt;
&lt;br /&gt;
So starting with Eagle Eye, at first it sounds like no big deal, and true Eagle Eye itself is nothing, when shotguns can't miss anyway. But no Eagle Eye and not being a [[Scout]] means you can't get [[Strategy:Intuition|Intuition]], which aside from being one of the most useful traits in general, is especially valuable for shotgun builds, as they can exploit shotguns maintaining perfect accuracy against enemies outside their vision range that Intuition lets you see, and it saves them precious shells by no longer having to [[radar shoot]] to make sure they don't walk into the view of something nasty. The fact you'll have to keep radar shooting throughout the game with MAD negates one of mastery's supposed advantages of saving you shells. Losing just Intuition wouldn't be a dealbreaker however, especially since it would have required picking up two dead levels in Eagle Eye to even get, but then...&lt;br /&gt;
&lt;br /&gt;
...Losing Hellrunner is a far bigger loss. Hellrunner itself is another very useful trait on its own regardless of build, as movement speed is so crucial in DRL, and a boosted [[dodging]] rate is also very handy to keeping you alive; nothing reduces damage more than not getting hit at all. But it's especially important for shotgun builds, as when you don't have the DPS to quickly smite enemies before they can hurt you, you're going to really need movement speed to limit damage you take, while fast movement speed is also needed to best utilize [[Strategy:Shottyman|Shottyman]]; after all the faster you can move, the faster you can reload with Shottyman, and the added dodging bonus of Hellrunner also ensures you're much safer when you're reloading with Shottyman in view of enemies. So with MAD, you'll be entirely dependent on equipment to increase your movement speed, which at best, will reliably come down to just [[Tactical boots]] and [[Tactical armor]], the latter of which will leave you very vulnerable with its complete lack of any protection; anything better will depend on getting lucky with rare [[Exotic]] and [[Unique]] drops. Also, since you need to take [[Strategy:Badass|Badass]] to get MAD, the knockback reduction from it nerfs your [[rocket jump]]s, making you even slower and making it even more difficult to get out of bad spots. On top of that with no Hellrunner, you can't get [[Strategy:Dodgemaster|Dodgemaster]], which does a lot to make open combat viable for shotguns, letting you dance through enemy attacks while simultaneously reloading with Shottyman, and it means you can no longer completely trivialize the [[Cyberdemon]], which is especially needed when your DPS is gonna be shit. At this point, Army of the Dead's viability is already tanked, but it doesn't stop here...&lt;br /&gt;
&lt;br /&gt;
The last trait that Army of the Dead blocks is... Finesse, which is arguably even worse than being blocked Hellrunner. Not being able to improve your firing speed has two big effects; first it significantly hinders your DPS, and when you already struggle for DPS as a shotgun build, losing out on one of your only ways to improve it obviously really really sucks. The second big effect is it also make you a lot less safe in general, as any time you fire nearly ensures enemies will be able to retaliate as long as they can see you, and again as a shotgun build, you really need to be able to compensate for your lackluster DPS by being able to fire and stay on the move to limit enemies being able to attack you. That isn't all though, being blocked Finesse blocks [[Strategy:Juggler|Juggler]], which is another big loss for shotgun builds when they'll be utilizing a variety of shotguns ''and'' making heavier usage of the [[Rocket launcher]] than other builds will, meaning you won't be able to quickly switch between whichever weapon is best for the situation at hand, nor pull off the &amp;quot;shoot shotgun, instantly pull out another shotgun to shoot without reloading&amp;quot; trick. The pain train doesn't even stop there, as blocking Finesse '''''also''''' blocks [[Strategy:Whizkid|Whizkid]]. Being blocked Whizkid means you'll only ever able to apply a single mod to any weapon or equipment '''ever''', which is gonna suck when there are multiple good exotic shotguns like the [[Assault shotgun]], [[Plasma shotgun]], and best of all, the [[Super shotgun]], that MAD users will not be able to trick out like other shotgun builds get the joy of. It additionally means you won't ever be able to make a [[Focused double shotgun]], leaving you stuck with the vastly inferior [[Double shotgun]] for your big boomstick if you're not lucky enough to find a Super shotgun, while you're gonna all-around move even slower and be less protected when you're only ever limited to a single mod per equipment and basic [[assemblies]]. Worst of all, if you are lucky enough to find a [[Nano mod]], you cannot make any [[Nano-shrapnel]] shotgun to potentially autowin the game, nor can you make [[Antigrav boots]] to salvage your terrible movement speed. For one last kick in the groin, through Whizkid, other shotgun builds can easily make their shotguns hit as hard or even harder than MAD's shotguns will with just multiple [[Power mod]]s and assemblies, so there completely goes any sort of advantage MAD could have had.&lt;br /&gt;
&lt;br /&gt;
So with Army of the Dead, you're much slower than other shotgun builds in every way, your DPS is much worse than other shotgun builds, and you ultimately don't even get the edge on lategame ammo efficiency when Whizkid can shore that up for other shotgun builds.&lt;br /&gt;
&lt;br /&gt;
==How to make Army of the Dead work==&lt;br /&gt;
If you're a masochist that still wants to give Army of the Dead a try at this point, first and most important thing to know is you're going to need to really ''really'' love [[corner shoot]]ing. Corner shooting is already a crucial component for shotguns and DRL as a whole, but MAD just takes it to an absurd level. Other shotgun builds can eventually get the all-around speed to be able to get into open firefights and come out on top, especially [[Strategy:Shottyhead|Shottyheads]] with their crazy firing speed, while [[Strategy:Fireangel|Fireangels]] can leverage their immunity to splash damage to zoom everywhere with rocket jumps and laugh at the VMR's futile attempts to harm them. But when your movement speed is ass, your firing speed is ass, and your DPS is bottom-of-the-barrel, the only way to survive is eternally hugging behind that corner and slowly taking things out one or two at a time when they come into view. If playing the whole game clinging behind corners just to survive is gonna bore you to sleep, absolutely do not play MAD outside of the easier difficulties, as ''you will fail'' trying to play MAD in any more aggressive way.&lt;br /&gt;
&lt;br /&gt;
The other vital thing to make MAD less awful to play is to invest in [[Brute]] and [[Berserker]], becoming a hybrid melee build. When you're so damn slow and your DPS is so shit, you realistically are just not going to be able to beat many of the bosses relying on your shotguns, without having very good armor and lots of [[Large medkit]]s. By having strong melee and Berserker, you'll be able to actually out-DPS them or at least won't need an insane amount of medkits to survive, while the guaranteed [[Longinus Spear]] or [[Azrael's Scythe]] from the [[Unholy Cathedral]] ensures you'll get an extremely powerful melee weapon for the late game that being able to use competently could save your ass if you ever find yourself having to fight in the open. Having the ability to get [[Berserk]]ed in general could also be the difference between survival and death, when it gives you such a big all-around speed improvement, on top of making you far tankier, something such a slow build really needs. One of the very few bright spots about MAD is that it lets you pick any one non-blocked trait of your choosing on the way to building to it, so you'll be able to pick up a level of Brute without delaying it and then get to Berserker only two more levels after getting MAD. It's probably a better idea however to delay getting MAD by heading straight to Berserker after spending your first three levels on the requisite two levels of [[Strategy:Reloader|Reloader]] and [[Strategy:Shottyman|Shottyman]], as [[Strategy:Badass|Badass]] is a pretty dead level and MAD isn't any sort of major boost as made very clear long ago, especially so on harder difficulties when Berserker + the [[Chainsaw]] might be the only thing that keeps you alive when staring down multiple [[Baron]]s, [[Commando]]s, and [[Revenant]]s near the end of Phobos. Hell, there might be an argument to go straight to Berserker at the start instead of Shottyman because it's so critical to patch up MAD's huge shortcomings (though you probably should just start with going straight to Shottyman, as making your Shotguns better will help you more in the early game, Brute isn't doing much before you get a [[Chainsaw]]). You might even end up finding yourself fighting in melee more often than actually using your shotguns with a MAD build, at which point, you might be wondering why didn't you just go with [[Strategy:Vampyre|Vampyre]]; it blocks [[Strategy:Eagle Eye|Eagle Eye]] (thus [[Strategy:Intuition|Intuition]]) and [[Strategy:Hellrunner|Hellrunner]] (thus also [[Strategy:Dodgemaster|Dodgemaster]]) too, but [[Strategy:Finesse|Finesse]] (and thus also [[Strategy:Whizkid|Whizkid]]) are still available, while Vampyre itself is a ''far more'' rewarding mastery than MAD could ever be. But if you're this insistent on trying out Army of the Dead, this is your best shot at making it work.&lt;br /&gt;
&lt;br /&gt;
As for trying to sidearm rapid-fire weapons or pistols with Army of the Dead, don't even try. With no Eagle Eye, your rapid-fire weapons aren't hitting anything worth a damn unless you're lucky enough to find a [[Laser rifle]] (in which case, it will be a very good sidearm weapon), and no Whizkid means you can't try to compensate for their inaccuracy by adding multiple [[agility mod]]s to them. Then with pistols, aside from them demanding more trait and inventory investment than melee does to become viable, no Whizkid just completely kills any pistol viability, as modding is absolutely essential to get a good pistol when there is no guaranteed pistol stronger than the basic peashooter you start with. So aside from investment in Brute and Berserker, that only leaves investing in [[Strategy:Ironman|Ironman]] and [[Strategy:Tough as Nails|Tough as Nails]] to try making yourself as tanky as possible. Do note that investing in Ironman even once means you can no longer guarantee activating Berserker from an [[Arch-vile]]'s blast, which can prove very clutch, so investing in TaN should probably be the priority. [[Strategy:Son of a Bitch|Son of a Bitch]] is an option too to try doing something to boost your crappy damage output, though considering how shotguns and melee see little relative benefit from it, especially when you have such poor firing speed, maximizing your survival is probably better (unless you find the aforementioned Laser rifle that is). As long as you're not investing in Ironman to keep the ability to easily get berserked from Arch-viles, you should invest in SoB before Ironman, but probably not before TaN.&lt;br /&gt;
&lt;br /&gt;
==Assemblies and miscellaneous tips==&lt;br /&gt;
Well with no [[Strategy:Whizkid|Whizkid]], Army of the Dead's choices for [[assemblies]] are very limited, but for what you can do, here are your options of particular note.&lt;br /&gt;
&lt;br /&gt;
*[[Tactical boots]] - An essential assembly for any build, but there is especially no argument for MAD not building them ASAP; this will be your best guaranteed source of improving your movement speed in the game, and there is little else you could use your [[agility mod]]s for as a shotgun build that can't even build a [[Focused double shotgun]].&lt;br /&gt;
&lt;br /&gt;
*[[Tactical shotgun]] - One mercy MAD gets is it can still build a Tactical shotgun, the most crucial weapon for any shotgun build that isn't lucky enough to find an [[Assault shotgun]] very early, so it's an obvious priority. It's probably even more vital for MAD, as given how slow they move, having to pump a [[Combat shotgun]] between shots is gonna be an even greater hindrance to them.&lt;br /&gt;
&lt;br /&gt;
*[[Elephant gun]] - Given that you're blocked from getting the Focused double shotgun, and can never apply more than a single [[power mod]] to any weapon, an Elephant gun is MAD's most ammo efficient weapon and most powerful option against enemies more than a few tiles away that the [[Double shotgun]] can't effectively damage, unless they're lucky enough to find the [[Super shotgun]]. Additionally, given the inability to use the mods much for elsewhere, MAD probably won't mind the cost of two power mods that other shotgun builds might balk at.  Just be really sure you have a [[shell box]] onhand when using this weapon, especially when relying on [[Strategy:Shottyman|Shottyman]] to reload isn't going to work as well with how slow you're gonna be.&lt;br /&gt;
&lt;br /&gt;
*[[Tactical armor]] - An armor with 0 protection and no [[resistance]]s is really unattractive, but this will be your best guaranteed source of movement speed via armor, and as long established, you need all the movement speed you can get. The 15% [[dodging]] rate it gives could save you too, and it's the only way to improve your base dodging rate without [[Strategy:Hellrunner|Hellrunner]]. You're probably still better off getting as protected as you can with your armor, but anything short of [[Red armor]] or a good [[exotic]]/[[unique]] armor is unlikely to do you better than this, and again you're probably not going to be putting those agility mods to much use elsewhere after making Tactical boots, so the mod cost isn't the concern it is to other builds. It will also make a good complimentary piece in general to your primary protection armor, when you can wear it to move around with some semblance of a decent pace, while switching to the heavier armor when dangerous combat is unavoidable.&lt;br /&gt;
&lt;br /&gt;
*[[Piercing blade|Piercing chainsaw]] - A Piercing chainsaw is normally inferior to just applying a [[bulk mod]] to a [[Chainsaw]], but there's one scenario where it really shines - fighting the [[Angel of Death]] to pierce through his insane 10 [[armor]]. Considering how important getting the [[artifact]] from the [[Unholy Cathedral]] will be to win the game with MAD, dedicating an assembly entirely for the purpose of beating it at the expense of having a slightly weaker melee weapon up to that point is very much worth it. This is especially so as with no [[Strategy:Finesse|Finesse]] investment to improve your attacking speed, and no actual melee mastery, you may find yourself losing the damage race with a standard Chainsaw against the Angel of Death on harder difficulties even with [[Strategy:Brute|Brute]] + [[Strategy:Berserker|Berserker]], especially if you don't find any armor with good melee resistance before then.&lt;br /&gt;
&lt;br /&gt;
*[[Power armor|Power Red armor]] - If you're lucky enough to find a [[nano mod]] with MAD, Power Red armor is really all you can do with it. With no Whizkid, you're blocked off from [[Nano-shrapnel]], [[Antigrav boots]], [[Cybernano armor]], and [[Nanofiber skin armor]], while a nano mod on its own won't do much for a shotgun. That just leaves Power Red armor, which is a bummer compared to the amazing game-breaking stuff that a nano mod can allow other builds to make, but Power Red armor is still an extremely good armor; it's practically a [[Fireproof armor|Fireproof Red armor]], except with a 25% melee ''resistance'' instead of -30% weakness, an extra point of protection, regenerating durability, and best of all, no movement penalty. It's not remotely game-breaking, but it's still probably the best armor a build with no Whizkid can ask for aside from maybe [[Malek's Armor]], which is an even luckier find than getting a nano mod.&lt;br /&gt;
&lt;br /&gt;
*[[Lava boots]] - If you get an [[onyx mod]] as MAD, and do not also find an [[Energy-shielded vest]], [[Phaseshift armor]], or [[Duelist armor]] to use that onyx mod on, nor found [[Enviroboots]] to freely walk through damaging fluids, it might actually be worth building Lava boots. Being able to freely walk through lava is such a tremendous advantage even if it slows you down a ton, as covered in the [[Cerberus boots]]' [[Strategy:Cerberus boots|strategy page]], of which MAD cannot ever build with its lack of Whizkid, while you won't get exceptional mileage out of using your lone mod slot on getting infinite durability for vanilla Red armor or any exotic armor that wasn't one of the three mentioned prior. Of course -30% movement speed when you're already so slow really really sucks though, so if you do build Lava boots as MAD, only put them on when going through lava is imperative, and be sure to immediately take them off once you get out of lava. You could build a [[Tower shield]] instead with that onyx mod to try maximizing your durability, but that 12 protection isn't quite as impressive as it looks with no resistances, and 150% durability that cannot be restored without a [[Megasphere]] won't last that long, nevermind the -50% movement speed penalty it has when you're already struggling so much for speed...&lt;br /&gt;
&lt;br /&gt;
Overall, while it may not be in the same shit tier as near-unusable masteries like [[Strategy:Bullet Dance|Bullet Dance]] and [[Strategy:Entrenchment|Entrenchment]], Army of the Dead fucking sucks. If you want to play a tanky [[Marine]] shotgun build, you would actually be better off going masterless. You'll still be a lot worse than [[Strategy:Shottyhead|Shottyhead]] and even [[Strategy:Fireangel|Fireangel]], and it overall would be a pretty mediocre build, but being able to actually invest in some combination of [[Strategy:Hellrunner|Hellrunner]], [[Strategy:Dodgemaster|Dodgemaster]], Finesse, [[Strategy:Juggler|Juggler]], and especially Whizkid will do so much more for you than getting piercing shotguns ever will. Pick Army of the Dead only if you are explicitly looking to challenge yourself by being denied these essential traits (it's the only reason I ever tried runs with MAD, which were never pleasant). Also for one final note, picking Army of the Dead in [[Angel of Shotgunnery]] looks like an attractive option because of how concerned people get about shell shortages in Hell, and indeed it's a popular choice for it, but there you will not have melee to bail you out when you get into a fight with a big horde or boss that you cannot possibly hope to out-DPS with your slow ass shotguns nor effectively evade with your snail-like mobility, while lategame ammo efficiency can be addressed by Whizkid as mentioned prior (while you can just always farm [[Sergeant]]s in an [[Arch-vile]] [[group]] for a bit if you need to, they're not uncommon). If you really don't like Shottyhead for whatever reason or are just tired of always picking [[Scout]]s and want to try something different, then the aforementioned masterless Marine build will do a lot better than MAD would. Also absolutely do not pick MAD in [[Angel of 100]], all those blocked traits just become even more important there; good luck surviving a [[Nightmare arachnotron]] [[cave]] when your movement speed is barely over 100% and you get near-instantly melted by a stream of plasma from all over after making a single move, not to mention how miserable it'll be to get all the mods you'll find over 100 levels and not be able to do shit with them. [[User:Omega Tyrant|Omega Tyrant]] ([[User talk:Omega Tyrant|talk]]) 22:56, 27 June 2023 (UTC)&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Strategy:Hey,_Not_Too_Rough</id>
		<title>Strategy:Hey, Not Too Rough</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Strategy:Hey,_Not_Too_Rough"/>
				<updated>2025-08-11T12:31:13Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
&lt;br /&gt;
Hey, Not Too Rough is trivial for DRL veterans, who will be able to win a standard game at this difficulty virtually every time no matter their build, unless they're playing some hard challenge. Make no mistake though, the jump from [[Strategy:I'm Too Young to Die|I'm Too Young to Die]] to HNTR isn't an easy one, and most newer players who jump to it after conquering ITYTD ''will'' get stomped at least their first few times (and those who claim otherwise are probably lying). Aside from more enemies, all those bonuses you had on ITYTD are gone; no more doubled ammo pickups, no more inaccurate enemies, no more half damaging [[fluids]], [[Small medkit]]s and [[Small Health Globe]]s no longer heal double, time-based powerups no longer have twice the duration, and you get a lot less EXP from each kill. Special levels additionally will be tougher; [[Phobos Anomaly]] in particular is the most notorious example, as while you just had a straight fight with the [[Bruiser brother]]s on ITYTD, you will now have to deal with a nasty [[Lost soul]] ambush that will assuredly wreck players their first time through. While you could get away with running around guns blazing on ITYTD thanks to all that extra ammo, health, and longer powerups, HNTR will kick your teeth in for doing the same and will make you learn the ropes of the game. If you find yourself struggling to get over the first hump for new players that is HNTR, here are some pointers that will help you out:&lt;br /&gt;
&lt;br /&gt;
*First and foremost, minimizing damage you take is important! With small health sources healing half what they did in ITYTD and enemies now hitting your more often, you can't just shrug off hits so easily anymore and will find yourself running out of health fast if you keep trying to tank hits.&lt;br /&gt;
&lt;br /&gt;
*Have you been [[Corner shooting]], [[Radar shooting]], and [[Gift dropping]]? These are vital survival techniques that will go a very long way in minimizing the damage you take, and are absolutely necessary to learn if you ever want to try taking on the difficulties beyond HNTR. If you don't know what those techniques are, '''''go read their respective pages right now''''' (if corner shooting still doesn't have a page by the time you read this, check out the strategy page for [[Strategy:The Wall|The Wall]] instead to get a good primer on how to corner shoot).&lt;br /&gt;
&lt;br /&gt;
*Pick your [[traits]] with a plan, picking traits at essentially random or whatever you think sounds cool at that moment will kneecap your attempts to overcome HNTR. If for example for your first five levels you went; [[Strategy:Son of a Gun|Son of a Gun]] -&amp;gt; [[Strategy:Badass|Badass]] -&amp;gt; [[Strategy:Brute|Brute]] -&amp;gt; [[Strategy:Reloader|Reloader]] -&amp;gt; [[Strategy:Son of a Bitch|Son of a Bitch]]; you'll be barely any stronger than you were when you first entered [[Phobos Base Entry]] and not be able to use any weapon particularly well, while now being at the point you're about to enter Phobos Anomaly and Deimos, where you will start regularly fighting enemies stronger than the measly formers and [[Imp]]s. If you don't have a strong grasp on the build you're going for and what traits will best facilitate your desired build, you should just plan a master trait you want from the outset and strictly only pick the traits that build to it to get your mastery as quick as possible, while then experimenting with other traits once you get your mastery. The optimal way to invest in traits doesn't necessarily require immediately gunning your mastery, plenty of high level DRL players have even claimed that going with no mastery is the most optimal build of all, but for newer players who don't yet fully understand the advantages of each trait, when most masteries generally require traits that facilitate their build and will largely block traits that would only serve as diversions, sticking to their mastery path will steer such players from picking the wrong traits and get them a fairly competent build.&lt;br /&gt;
&lt;br /&gt;
*You will have to start considering the risk/reward of entering special levels, and in turn recognize when you will have to pass up on entering a special level as you don't have the resources to realistically beat it, instead of just blindly going down every set of red stairs you see. One perk of &amp;quot;graduating&amp;quot; to HNTR is that you can encounter all those special levels that didn't show up on ITYTD, but this exemplifies even more that special levels will not always be beatable. [[Unholy Cathedral]] and [[The Mortuary]]/[[Limbo]] are the most notorious examples, as players will have many runs that just will not have what it takes to beat those levels by the time they appear, and trying to do so will ensure a grisly demise. You will also have to recognize when you can only partially clear out a special level and be willing to cut your losses if things get too dicey. E.g. did you clear out [[Deimos Lab]] and just have the [[Shambler]]s left, but you got no medkits left nor even a healthy [[Blue armor]]? You best not hit the switches to release them and just leave with what you got, unless you want to kiss your run goodbye.&lt;br /&gt;
&lt;br /&gt;
*Learn the [[assemblies]]! Assemblies can get you some very good equipment that doesn't rely on you getting lucky with an [[exotic]] or [[unique]] drops, and equipment can do more to power you up than just traits will. [[Tactical boots]] and [[Fireproof armor]] (particularly on [[Red armor]]) are two basic assemblies in particular that are easy to make every run and will be very helpful to about any build, if you haven't been building them start doing so. The [[Tactical shotgun]] is another very good basic assembly that's not only vital for shotgun builds, but will be very useful to any other build that keeps a shotgun handy for their utility purposes and corner shooting, as long as they can spare the mods for it. Be sure to check each assembly's strategy page for more helpful information on how they're best utilized, though be sure to try experimenting with them yourself, just building the aforementioned three basic assemblies will do a lot of heavy lifting.&lt;br /&gt;
&lt;br /&gt;
*Be mindful of your ammo consumption. You shouldn't be struggling for ammo on HNTR, but still if you are just shooting blindly at everything and making no effort to stockpile ammo, you may find the reduced ammo pickups to start stinging you a bit. Try to carry at least a few stacks of ammo for your build's primary weapon, and if you're a shotgun build, try to make that four or five before you enter Hell. Also pay attention to the enemies that are in a level and try to actively utilize weapons they will replenish. Are there [[Former sergeant]]s abound? Go loose with your shotguns. [[Former captain]]s? Rev up your [[pistol]]s or [[chaingun]]. [[Revenant]]s and [[Mancubi]]? Get some use out of your [[rocket launcher]]. Are [[Former commando]]s lurking or a bunch of [[Arachnotron]]s stomping around? Get less stingy with your plasma weapons.&lt;br /&gt;
&lt;br /&gt;
*Don't immediately grab powerups the instant you see them. Find a salivating [[Berserk Pack]] or [[Invulnerability Globe]], but you're in good shape as is and most of the enemies on the level are already dead? Leave them, mop up the rest of the level, and then grab them right before you go to the next level; you will carry powerup effects with you into the next level, and often the immediate beginning of a level can be the hardest part, as DRL loves to spawn you in a room full of baddies (which becomes progressively more common the higher the difficulty). Conversely, don't try to hoard powerups too much; if you're getting your ass kicked in a level or there's a nasty situation coming up, go retreat to your powerups and get them ASAP, those powerups can't help you if you died before you could even use them.&lt;br /&gt;
&lt;br /&gt;
*On a related note, try to avoid hoarding your items and actually use them in the moments that they're needed. It might sting to have to &amp;quot;waste&amp;quot; a [[Large medkit]] when you're at only 50% health, as you may have wanted to save it for when you're on the brink of death to get more mileage out of it, but it is often better to be safe than sorry when you got enemies around who can suddenly wipe out half your health. Don't end up like the countless players who died with an inventory full of medkits.&lt;br /&gt;
&lt;br /&gt;
*Have you learned what [[run]]ning is and utilized it yet? Have you also learned [[rocket jump]]ing? These are vital abilities '''''that will''''' save your ass in countless runs, and getting the hang of how to utilize them is absolutely necessary if you're gonna ever try playing the difficulties above HNTR.&lt;br /&gt;
&lt;br /&gt;
That should cover much of the basics. Before long, you should get a broader understanding of how to play D the Roguelike and be able to conquer Hey, Not Too Rough, but don't feel bad if it takes you several runs to get your first victory, every failed run is a learning experience. Once you do get a handle on HNTR and the standard game is no longer much of a challenge, you can try the various [[Angel Challenges]], which you wouldn't have been able to play before on ITYTD, and then you can start thinking of making the next step to [[Strategy:Hurt Me Plenty|Hurt Me Plenty]]. [[User:Omega Tyrant|Omega Tyrant]] ([[User talk:Omega Tyrant|talk]]) 08:49, 8 July 2023 (UTC)&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Strategy:Tactical_boots</id>
		<title>Strategy:Tactical boots</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Strategy:Tactical_boots"/>
				<updated>2025-08-11T12:30:49Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{infostrat switch}}&lt;br /&gt;
&lt;br /&gt;
==Patch notes==&lt;br /&gt;
===Pre-0.9.9.4===&lt;br /&gt;
Tactical Boots had 1 [[protection]], gave +20% movement [[speed]], gave -25% [[knockback]], and regenerated 1% durability per action.&lt;br /&gt;
&lt;br /&gt;
===0.9.9.4===&lt;br /&gt;
Tactical Boots's movement speed bonus was nerfed to 10%, and its knockback resistance was reduced to -15%.&lt;br /&gt;
&lt;br /&gt;
===0.9.9.6===&lt;br /&gt;
Tactical Boots now have 0 protection, but its movement speed was buffed up to +15%, the knockback resistance was removed, and it gives a +10% dodging bonus. Its regeneration was also buffed to recover 2% durability per action, albeit it now doesn't start regenerating until 5 actions without being damaged.&lt;br /&gt;
&lt;br /&gt;
===0.9.9.7===&lt;br /&gt;
Tactical Boots was nerfed by having the dodging bonus removed entirely.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
Tactical Boots is one of the big three staple assemblies alongside [[Fireproof armor]] and the [[Tactical shotgun]], and almost certainly reigns supreme as the most commonly made assembly of all. Only +15% movement speed doesn't sound amazing, and having no protection for your feet sounds bad when that is supposed to be the point of boots, but faster movement speed is very important for offensive and defensive purposes. Being able to outmaneuver even lowly [[Imp]]s without having to activate [[Run]] is a lot more useful than you would think, let alone outmaneuvering [[Hell knight]]s and [[Baron]]s that are the bane of players on Phobos when playing [[Ultra-violence]], and having your running speed be faster than [[Demon]]s, [[Revenant]]s, and [[Arachnotron]]s without [[Hellrunner]] will absolutely save your ass. You can read Hellrunner's [[Strategy:Hellrunner|strategy page]] for all the virtues that having faster movement speed grants.&lt;br /&gt;
&lt;br /&gt;
The main thing that makes Tactical Boots so good is its cheap investment cost and its splashability. To assemble, it just requires common [[Steel boots]] and two [[agility mod]]s, the ingredients for which you can sometimes have after [[The Chained Court]] and will usually have before [[Phobos Anomaly]] if you don't skip out on [[Military Base]]/[[Phobos Lab]]. Then when it comes to splashability, every build in any sort of challenge benefits significantly from having more movement speed, so you'll want more movement speed as soon as you can get it. Now as mentioned earlier, Tactical Boots provide absolutely no protection against [[fluids]], but the thing is you can usually just avoid running into them, so the movement speed of your boots is far more important, and if you are concerned about scenarios where you're forced to run across fluids to progress or fighting in situations where you risk getting knocked into a pool of acid/lava, you can just carry another pair of boots with better protection while wearing your Tactical Boots for all other situations. Another knock one may levy against Tactical Boots is that the second agility mod to assemble only adds +5% movement speed over what the first agility mod added to the requisite Steel Boots (or any other pair of standard boots), while adding it to your [[armor]] instead will give it +15% movement speed, overall giving you an effective +25% movement speed boost when combined with the A-modded Steel Boots. However, the other thing that makes Tactical Boots great is that you'll get to always keep them on to always benefit from its speed boost (and their durability even regenerates if they get damaged, so you should never lose them), whereas you'll be constantly cycling through armors from them getting worn down or to utilize armor more suited for the battle at hand, so it'll generally serve you best to prioritize making your boots faster before your armors (not to mention that you'll be very unlikely to have anything better than [[Blue armor]] before the guaranteed [[Red armor]] in Phobos Anomaly).&lt;br /&gt;
&lt;br /&gt;
For the final note on Tactical Boots, you can make their movement speed even faster if you got [[Whizkid]] 2, which allows you to apply a single mod to assemblies. There is no need to bother going through the other mod options, applying an agility mod is the only mod you should consider for your Tactical Boots, adding another +10% movement speed and overall giving +25% movement speed, tied with A-modded [[Phaseshift boots]] for the second fastest boots and only beaten by [[Antigrav boots]] that require a rare [[nano mod]] to create. Unfortunately in 0.9.9.7, you can only mod assembles you made ''after'' you get WK2, and since Tactical Boots is an assembly you'll almost always make in Phobos while WK2 is something you'll usually pick up at least a few levels into Deimos, you'll rarely get to utilize this outside of [[Angel of 100]] unless you're willing to put off assembling your Tactical Boots until you get WK2 or are willing to make another pair after getting WK2, either scenario usually being unideal. Fortunately in the upcoming long-awaited 0.9.9.8, WK2 had that dumb restriction removed and so you'll be able to mod your assemblies regardless of when you made them, allowing you to put another agility mod on those early Tactical Boots you make and solidifying this assembly's place as '''''the''''' staple assembly of DRL. [[User:Omega Tyrant|Omega Tyrant]] ([[User talk:Omega Tyrant|talk]]) 09:17, 6 July 2024 (UTC)&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Strategy:Double_shotgun</id>
		<title>Strategy:Double shotgun</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Strategy:Double_shotgun"/>
				<updated>2025-08-11T12:30:04Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{infostrat switch}}&lt;br /&gt;
== Main Guide (v0.9.9.5) ==&lt;br /&gt;
&lt;br /&gt;
=== General Tactics ===&lt;br /&gt;
Basic strategy posted by [[User:Kashi|Kashi]] 19:11 January 12, 2012 (GMT).&lt;br /&gt;
&lt;br /&gt;
Ah, the Double Shotgun, one of the most emblematic weapons that ever existed in the game. It's the bigger, nastier brother of the normal shotgun, carrying an even deadlier pack that comes on a two-hitting blast, sending enemies flying towards the unknown in just one go. Still, while this weapon has very good pros, the cons balance them, turning what could be a gamebreaking weapon into a merely incredible one, depending on the use one gives to it. Yes, its strenghts are limited to what one decides to do, because the many drawbacks it has (Its range being the main one) turns it into a bad choice to use most of the time, unless one has the corresponding traits that bring out the best qualities of the weapon itself.&lt;br /&gt;
&lt;br /&gt;
The main use of the double shotgun, which is a marked difference to other [[Damage_type#Shrapnel|shrapnel-based]] weapons in the game, is at short range while dealing with packs of mobs, as the weapon itself has an horrendous damage reduction based on the range, limiting the pain it can cause to the monsters if the are beyond 6 squares from the player. This is normally a problem for new players, as it's common to make the mistake of firing the double shotty as a long-range weapon, failing to cause any harm to the enemies. Another problem it has is that it consumes ammo the same as a fat child eating candies, as each fire makes use of '''two''' shots per use, combining it with a 2 second reload time, double of what the normal shotty has.&lt;br /&gt;
&lt;br /&gt;
Still, this weapon can be a lifesaver when in a pinch (And by pinch, we mean &amp;quot;Surrounded by mobs&amp;quot;), as each shell fired from it counts as separate attacks, dealing damage and sending knockback '''separately'''. This can be translated as &amp;quot;The enemy flies farther and get damaged even more than with a normal shotty&amp;quot;. Even though, the same disadvantages other shotguns have, namely the &amp;quot;shrapnel&amp;quot;-type of damage they cause, appear on the double shotgun, as it makes it a terrible choice when dealing with armored enemies, unless one assembles a [[Plasmatic shrapnel]] or gets the trait [[Traits#Army_of_the_Dead|Army of the Dead]].&lt;br /&gt;
&lt;br /&gt;
While the weapon itself carries on with its good use even at late-game, the main problem that affects it at that stage is the same that can happen everytime, which is the lack of ammo. This, at the beginning, can be slightly handwaved, as enemies that drop shells are common, but during late-game levels, the number of spawned former sergeants drop, marking an end to the weapon itself, unless one makes use of the Plasmatic Shrapnel as a self-producing ammo factory, of course.&lt;br /&gt;
&lt;br /&gt;
=== Modifications ===&lt;br /&gt;
At the current version of DRL (0.9.9.5), there are three possible assemblies that can be used on this weapon. Interestingly enough, two of them makes use of a unique mod that doesn't appear very often.&lt;br /&gt;
&lt;br /&gt;
The first one, and the most simple is the Plasmatic Shrapnel, which can come in two flavors depending the way in which the shotgun gains more damage (And the eponymous change in damage type) or it gains the ability to manufacture its own ammo (At the cost of reloading) and gaining the plasma damage, too. This, while making use of a rare Nano Pack, it eliminates some of the disadvantages the weapon has, turning it into a viable choice even at late stages due to the change from shrapnel to plasma damage, also solving the ammo problem. Still, this doesn't do a thing about the lack of range, which is solved by another assembly.&lt;br /&gt;
&lt;br /&gt;
Next comes the [[Nano-shrapnel]], which can do the same as the Plasmatic Shrapnel, but changing the damage type of the weapon to piercing instead of plasma. In my honest opinion, while this one ignores armor altogether, plasma can be better, because of the ability to destroy walls. Same thing, but it can be a bit stronger, depending how do you assemble the mods.&lt;br /&gt;
&lt;br /&gt;
And the last, but not least, is the [[Focused double shotgun]], a souped-up version of the unmodded double shotty, which raises the damage it can cause, while changing the type of spread the weapon has. That, for starters, solve the problem with the range, as it gives it the same range as a normal shotgun. That means that mobs don't need to be as close as before. A good choice when you're doing a AoSh run, considering the fact that it doesn't rely on a rare level drop as the Nano Pack.&lt;br /&gt;
&lt;br /&gt;
=== Trait Usage ===&lt;br /&gt;
There are several ways to bring out the best use of a double shotty in a game, be it a standard one or a challenge, most of them related to the character build used by the player. Obviously, all of them makes use of [[Traits#Shottyman|Shottyman]], because it makes moving and reloading a combined action, no longer wasting time as a sitting duck while you pump shells into your boomstick. This, combined with the fact that reduces the reloading time (Due to the Reloader L2 traits) and the fact that shotguns have perfect accuracy, can ensure that being hit by the enemies is as hard as it gets, even better if the player is running, as there is no drop-off in the aiming of the weapon.&lt;br /&gt;
&lt;br /&gt;
In the case of damage-boosting, the trait to go is [[Traits#Son_of_a_Bitch|Son of a Bitch]], which grants a good +1 per trait level to the damage caused per shot, which basically means that the double shotty gets a free 2 damage to each enemy caught up in the blast in SoB L1. Pretty amusing to see those demons gibbed, yup.&lt;br /&gt;
&lt;br /&gt;
When it comes to master traits, it depends on the way you want to have your weapon built with assemblies. A normal choice is [[Traits#Fireangel|Fireangel]], combined with the use of one of the assemblies that help ignore the armor of an enemy, be it Plasmatic or Nano-Shrapnel. Fireangel grants immunity to explosion damage (i.e: rockets, barrels, the Archvile AoE attack's splash damage, the Cacodemons' plasma ball, etc), raises the evasion of the character and the movement speed (Because of [[Traits#Hellrunner|Hellrunner]], grants a free [[Traits#Dodgemaster|dodge by sidestepping]] and also reloads the shotgun on movement.&lt;br /&gt;
&lt;br /&gt;
Another choice is the previously mentioned Army of the Dead, which turns the shotgun into an armor-piercing stick of death against... pretty much everything in the game. Double health (Via [[Traits#Badass|Badass]]) and reloading on movement turns this trait into a secondary viable option, especially if you combine it with the powerhouse that is the Focused Double Shotgun, which deals incredible damage in one go to all enemies in the cone of fire. Still, you have to stock shells like hell, because the shortage can prove to be a pain in the ass later on.&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Lever</id>
		<title>Lever</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Lever"/>
				<updated>2025-08-11T12:29:54Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Levers are basic objects that appear on occasion throughout DRL. By definition they are items, but are more akin to [[Items#Powerups|powerups]] than anything else: they can be destroyed by splash damage rather easily and tend to disappear on use. Levers are always associated with the &amp;lt;font-family:monospace&amp;gt;&amp;amp;&amp;lt;/font&amp;gt; symbol.&lt;br /&gt;
&lt;br /&gt;
In random levels, many different types of levers are created and are normally indistinguishable from one another. By investing in the [[Intuition]] trait, more information can be known about the lever before pulling it. The following is a list of all random levers and the information regarding them:&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;border: 2px solid darkred; border-spacing: 0; font-size: 90%; margin: 0.25em 0.5em;&amp;quot;&lt;br /&gt;
 {{Table5Col+Header&lt;br /&gt;
  |hs=background: darkred; color: yellow; font-size:&lt;br /&gt;
  |h1=text-align: center|h2=text-align: center|h3=text-align: center|h4=text-align: center|h5=text-align: center&lt;br /&gt;
  |'''Exact Description'''|'''General Description'''|'''Uses'''|'''Map-wide [[Level feeling]]'''|'''Effect'''&lt;br /&gt;
  |es=background: #333;&lt;br /&gt;
  |c1=vertical-align:center; align:top; padding:0px 2px;&lt;br /&gt;
  |c2=vertical-align:center; align:top; padding:0px 2px;&lt;br /&gt;
  |c3=vertical-align:center; align:top; padding:0px 2px;&lt;br /&gt;
  |c4=vertical-align:center; align:top; font-style: italic; padding:0px 2px;&lt;br /&gt;
  |c5=vertical-align:center; align:left; padding:0px 2px;&lt;br /&gt;
  |floods with water|neutral|1|The air is really humid here...|Sets all cells unoccupied by barrels or doors with water in the room/map.&lt;br /&gt;
  |floods with acid|dangerous|1|In the State of Denmark there was the odor of decay...|Sets all cells unoccupied by barrels or doors with acid in the room/map.&lt;br /&gt;
  |floods with lava|dangerous|1|You feel that smell? That gasoline smell? Oh hell...|Sets all cells unoccupied by barrels or doors with lava in the room/map.&lt;br /&gt;
  |explodes barrels|neutral|1|N/A|All barrels on the map are simultaneously detonated.&lt;br /&gt;
  |destroys walls|dangerous|1|You hear the trumpets of Jericho echoing in the distance...|Destroys all surrounding walls in the room, or all walls on the floor if it's a map-wide lever (excluding border walls).&lt;br /&gt;
  |harms creatures|beneficial|1|The smell of a massacre...|Hits all enemies in the room/map with 20 [[fire]] damage.&lt;br /&gt;
  |spawns enemies|dangerous|1-3|N/A|Spawns a random number of enemies directly adjacent to the lever: these enemies give no experience and are based on the current danger level, but will still drop any inventory the enemy normally drops.&lt;br /&gt;
  |repairs armor|beneficial|1-3|N/A|Repairs currently-equipped armor and boots by 25%. Note that this is different from an [[armor shard]], which repair boots by 10%. This lever will not activate if you have no armor nor boots equipped that can be repaired. Its repairing amount is additionally not doubled in the [[I'm Too Young to Die]] and [[Nightmare!]] difficulties.&lt;br /&gt;
  |heals player|beneficial|1-3|N/A|Heals player by the same amount as a [[small med-pack]]. This lever will not activate if you already have 100% or more health. Its healing amount is additionally not doubled in the I'm Too Young to Die and Nightmare! difficulties.&lt;br /&gt;
  |ammo dispenser|beneficial|2-4|N/A|Drops a stack of [[10mm ammo]], [[shotgun shell]]s. [[rocket]]s, or [[power cell]]s. The ammo dropped is compatible with what weapon you have equipped when activating the lever, and the amount of ammo in each stack is not affected by the difficulty ammo multiplier. This lever cannot be activated if you're equipping a melee weapon or weapon that uses unconventional ammo.&lt;br /&gt;
  |}}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Modding:Tutorial/Designing_AI</id>
		<title>Modding:Tutorial/Designing AI</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Modding:Tutorial/Designing_AI"/>
				<updated>2025-08-11T12:29:48Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{incomplete}}&lt;br /&gt;
Before the more recent versions of DRL, all beings other than the player used a single algorithm for AI, or artificial intelligence, that directed how the being should act under certain circumstances. Although this default AI is modifiable to some extent through a few being flags, the extent to which beings acted remained roughly the same. When it became clear that this default AI could be outwitted with clever tactics, the AI object was added into the game (sometimes known as &amp;quot;lua AI&amp;quot;), allowing for complete customizability as to what a being does given any circumstances. Most beings, as of v0.9.9.4, call a particular AI object that governs their actions, and are thus more difficult to fight when playing the game (which is a good thing).&lt;br /&gt;
&lt;br /&gt;
This tutorial goes through the basics of creating AI objects and what you can do with them. The AI object class is very flexible in that the basic structure is extremely simple, allowing you to add almost anything that the game allows from within its API. Unsurprisingly, designing your own artificial intelligence can be an extremely challenging task, depending on what exactly you want the AI to be capable of. Basic structuring techniques will be explained, as well as general guidelines when writing the code that your AI will consist of.&lt;br /&gt;
&lt;br /&gt;
==Base Prototype==&lt;br /&gt;
&lt;br /&gt;
Since the AI object is so very simple in its required fields, all of them will be contained in the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
AI{&lt;br /&gt;
    name = &amp;quot;simple_ai&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    OnCreate = function(self)&lt;br /&gt;
        self:add_property(&amp;quot;ai_state&amp;quot;, &amp;quot;first_state&amp;quot;)&lt;br /&gt;
        ....&lt;br /&gt;
    end,&lt;br /&gt;
&lt;br /&gt;
    OnAttacked = function(self)&lt;br /&gt;
        ....&lt;br /&gt;
    end,&lt;br /&gt;
&lt;br /&gt;
    states = {&lt;br /&gt;
        first_state = function(self)&lt;br /&gt;
            ....&lt;br /&gt;
        end,&lt;br /&gt;
&lt;br /&gt;
        ....&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*''name'' is the identifier of the AI object, to be used as the field value for the being key ''ai_type''.&lt;br /&gt;
*'''OnCreate'''(''self'') triggers whenever ''self'' is created. For any being using this AI object, it is functionally identical to that being's '''OnCreate()''' hook in its own prototype.&lt;br /&gt;
**The &amp;quot;required&amp;quot; property here, ''ai_state'', is the key factor when determining what subfunction the being should run in the AI object.&lt;br /&gt;
*'''OnAttacked'''(''self'') triggers whenever ''self'' is hit. The hit does not have to cause damage. (Such a requirement can be a condition within the hook by comparing HP across multiple actions.)&lt;br /&gt;
*''states'' is an array of functions that are called based on the value of ''ai_state''. These functions will be run immediately after the being's own '''OnAction()''' hook in its own prototype. In the above example, since ''ai_state'' is set to &amp;quot;first_state&amp;quot; during '''OnCreate()''', the being will run the '''first_state()''' function.&lt;br /&gt;
&lt;br /&gt;
Technically speaking, the &amp;quot;state&amp;quot; system of the AI object need not be used: one can instead invoke '''OnAction'''(''self'') directly. However, states are a very practical way to organize the various actions or modes that the AI transitions through, and its system will be used throughout this tutorial. Even including the optional state system, however, what is shown above is all that is necessary for the AI object to initialize.&lt;br /&gt;
&lt;br /&gt;
==AI Rules==&lt;br /&gt;
While you are free to develop your artifical intelligence however you want, there are still some fundamental laws that govern their structure. (They are not so much mandated out of standardization as they are out of necessity: AI objects that do not follow these rules will not run correctly.)&lt;br /&gt;
&lt;br /&gt;
===Rule 1===&lt;br /&gt;
'''&amp;lt;big&amp;gt;The AI must always lower the being's energy.&amp;lt;/big&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
Energy, or ''scount'', is determines when the being can take an action, and so long as its energy remains the same, it can continuously take more and more actions until the game refuses to allow a continuation (ie, infinite loop error). There are a number of API functions that will automatically cause the being's energy to decrease, but when none of these functions are called, you must directly lower the being's scount in the following manner:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
self.scount = self.scount - 1000&lt;br /&gt;
self.scount = self.scount - 10*self.speed&lt;br /&gt;
self.scount = 4000&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While these three examples may appear similar, they are quite different. Recall that ''scount'' increases by ''speed'' each game turn, and decreases by 100 multiplied by the number of game turns for default actions (e.g., moving or attacking). Knowing this, we can see three separate possibilities:&lt;br /&gt;
&lt;br /&gt;
*The first, reducing ''scount'' by 1000, will require a being with ''speed'' set to 100 to wait exactly ten game turns. For beings with ''speed'' greater than 100, it will occur sooner, and for beings with ''speed'' less than 100, it will occur later. Thus, a being with an action modified by this method will act &amp;quot;constant&amp;quot; with respect to its default action speed.&lt;br /&gt;
*The second, reducing ''scount'' by 10 multiplied by the being's speed, will require any being, regardless of ''speed'', to wait exactly ten game turns. Thus, a being with an action modified by this method will act &amp;quot;global&amp;quot; with respect to its default action speed (that is, all beings across the global scale take the same amount of time).&lt;br /&gt;
*The third, setting ''scount'' to 4000, is functionally identical to the first, except that it can be used immediately after default actions in order to make ''scount'' decrease by a very specific value. Suppose you wanted a being to be able to equip things immediately: using this method you can reset the scount value (to 5001) in order for the process to have taken no virtually no time at all. (Technically you could compare ''scount'' before and after actions taken, but this is a much simpler method.) Thus, a being with an action modified by this method will act &amp;quot;independent&amp;quot; with respect to its default action speed.&lt;br /&gt;
&lt;br /&gt;
You will almost always use the &amp;quot;constant&amp;quot; modifier, but don't forget about the other two. (In particular, &amp;quot;global&amp;quot; and &amp;quot;independant&amp;quot; modifiers become important when you have several beings using the same AI and want to coordinate their actions very precisely.)&lt;br /&gt;
&lt;br /&gt;
===Rule 2===&lt;br /&gt;
'''&amp;lt;big&amp;gt;Changing states in an AI during a single action always requires a way to exit the current state.&amp;lt;/big&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
There are two ways to exit a function: break and return. Consequently, there are two ways to switch states:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
AI{&lt;br /&gt;
    name = &amp;quot;two_state&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    OnCreate(self)&lt;br /&gt;
        self:add_property(&amp;quot;ai_state&amp;quot;,&amp;quot;state1&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    states = {&lt;br /&gt;
        state1 = function(self)&lt;br /&gt;
            return(&amp;quot;state2&amp;quot;)&lt;br /&gt;
        end,&lt;br /&gt;
&lt;br /&gt;
        state2 = function(self)&lt;br /&gt;
            self.scount = self.scount - 1000&lt;br /&gt;
        end,&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return method is a single line that both ends the function prematurely and sets the new ''ai_state''. In the above function, the being begins in '''state1()''', at which point it immediately changes to '''state2()''', then ends in '''state2()''' (since ''scount'' has decreased when that state ends).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
AI{&lt;br /&gt;
    name = &amp;quot;two_state&amp;quot;,&lt;br /&gt;
    ....&lt;br /&gt;
    states = {&lt;br /&gt;
        state1 = function(self)&lt;br /&gt;
            self.ai_state = &amp;quot;state2&amp;quot;&lt;br /&gt;
            break&lt;br /&gt;
        end,&lt;br /&gt;
&lt;br /&gt;
        state2 = function(self)&lt;br /&gt;
            self.scount = self.scount - 1000&lt;br /&gt;
        end,&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If changing states with the break method, you'll have to establish what state you're changing to first by modifying the &amp;quot;ai_state&amp;quot; property, then follow it with a break.  On the surface, this is like the return method with an extra line. However, you can split the functionality when you assign the ai_state and when you break, in case you expect to purposefully want the state to repeat itself (and are reasonably certain that it will not tend toward an infinite loop error). In many cases, however, you should use the return method to immediately switch to another state.&lt;br /&gt;
&lt;br /&gt;
Note that, were there no break or return in '''state1()''', even if ''ai_state'' was modified, the state will continuouslly repeat until an infinite loop error occured. This is unique to the AI object, due to the way that ''ai_state'' is handled.&lt;br /&gt;
&lt;br /&gt;
===Rule 3===&lt;br /&gt;
'''&amp;lt;big&amp;gt;Always make sure that the AI will end a being's turn.&amp;lt;/big&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
This is a more subtle rule, as it already implies that the first two rules have already been addressed. In short, it is necessary that you make sure your conditions are always comprehensive in either changing states or lowering the being's energy. &lt;br /&gt;
&lt;br /&gt;
This tutorial adopts some terminology regarding the completeness of states:&lt;br /&gt;
&lt;br /&gt;
*'''Infinite''' states have obvious flaws that will cause a being to return an infinite loop error. AI objects with infinite states should always be fixed. However, infinite states can be used as a debugging tool: since infinite loops can easily be traced to a particular condition, they are a useful way to find a problem with the AI.&lt;br /&gt;
*'''Finite''' states will always either change to another state or cause the being's turn to end, regardless of the being's circumstances. Ideally, all states should be finite.&lt;br /&gt;
*'''Indefinite''' states, while not explicitly finite, will only cause infinite loop errors in unlikely circumstances. Sometimes it is feasible to fix these &amp;quot;indefinite conditions&amp;quot;, sometimes not: these can be used in modules but care should be taken to avoid circumstances in which the error may manifest. (The simplest way to prevent an infinite loop is to simply set a limit on how much a loop can repeat itself, either with a loop counter or a finite iterator.) The most common indefinite states involve properties that are not explicitly defined in the AI, but belong to beings that use the AI.&lt;br /&gt;
&lt;br /&gt;
States that satisfy rule 3 are considered finite, and when every state of an AI object is finite, the object itself is considered finite as well.&lt;br /&gt;
&lt;br /&gt;
Let us suppose we want to construct an AI that only traveled up. Here is a simple example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
AI{&lt;br /&gt;
    name = &amp;quot;up_ai&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    OnCreate = function(self)&lt;br /&gt;
        self:add_property(&amp;quot;ai_state&amp;quot;, &amp;quot;walk_up&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    states = {&lt;br /&gt;
        walk_up = function(self)&lt;br /&gt;
            local up_coord = self:get_position() + coord.new(0,-1)&lt;br /&gt;
            self:direct_seek(up_coord)&lt;br /&gt;
        end,&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Any being with this AI will enter the &amp;quot;walk_up&amp;quot; state, get its position, add that coord to an upward-facing unit coord, and use the '''being:direct_seek()''' to move precisely to the new position. This is fairly complete, because the new position is only one tile away, so '''being:direct_seek()''' will never cause the being to run into obstacles between the being's position and the target position.&lt;br /&gt;
&lt;br /&gt;
However, what happens when the tile above the AI is, itself, an obstacle? In such a case, '''being:direct_seek()''' does not perform a move, which means that the being's energy does not lower, and so the being is stuck in an infinite loop! We have created an infinite state and want to immediately resolve this problem. Fortunately, there is an easy way to deal with the loop, thanks to the way that movement methods work:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
AI{&lt;br /&gt;
    name = &amp;quot;up_ai&amp;quot;,&lt;br /&gt;
    ....&lt;br /&gt;
    states = {&lt;br /&gt;
        walk_up = function(self)&lt;br /&gt;
            local up_coord = self:get_position() + coord.new(0,-1)&lt;br /&gt;
            if self:direct_seek(up_coord) ~= 0 then&lt;br /&gt;
                self.scount = self.scount - 1000&lt;br /&gt;
            end&lt;br /&gt;
        end,&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''being:direct_seek()''' returns an output integer, depending on what happens inside of the method. For our purposes, the method returns 0 whenever the being moves and returns a different number whenever it doesn't. Knowing this, we can set up a conditional checking to see if the return value is zero or not. If it is not, we cause the being to wait by lowering its energy. With our new condition, the being will move up until it can't, at which point it will do nothing; if the obstacle in the being's way is cleared, it will resume moving up. We have now formed a finite state, and since the AI only consists of a single state, we can consider the AI finite as a whole.&lt;br /&gt;
&lt;br /&gt;
If you keep these rules in mind, you will have fewer problems in running the various algorithms within your AI.&lt;br /&gt;
&lt;br /&gt;
==Default Actions==&lt;br /&gt;
There are a number of being methods that will automatically cause the being to lower its energy. Many of them are critical in developing an AI for DRL, and you would do well to memorize them:&lt;br /&gt;
&lt;br /&gt;
===being:direct_seek()===&lt;br /&gt;
'''being:direct_seek'''(''coord'')) commands ''being'' to take a step toward ''coord'' following the most direct path possible. The direct pathing used here is the same as the game's default AI, and its algorithm can be roughly described by the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
calculate the x-distance &amp;quot;dx&amp;quot; and y-distance &amp;quot;dy&amp;quot; from the target coordinate&lt;br /&gt;
&lt;br /&gt;
if dx != 0 and dy != 0&lt;br /&gt;
  attempt to move {sign(dx),sign(dy)}*&lt;br /&gt;
  if move failed&lt;br /&gt;
    if dy &amp;gt;= dx&lt;br /&gt;
      attempt to move {0,sign{dy})&lt;br /&gt;
      break on failure&lt;br /&gt;
    else&lt;br /&gt;
      attempt to move {sign(dx),0}&lt;br /&gt;
      break on failure&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
elseif dx == 0&lt;br /&gt;
  attempt to move {0,sign(dy)}&lt;br /&gt;
  break on failure&lt;br /&gt;
elseif dy == 0&lt;br /&gt;
  attempt to move {sign(dx),0)&lt;br /&gt;
  break on failure&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
if break occurred, end turn&lt;br /&gt;
&lt;br /&gt;
*sign(x) is +1 for positive x and -1 for negative x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''being:direct_seek()''' returns an integer, which determines what occured with the being attempted to move:&lt;br /&gt;
&lt;br /&gt;
*'''0''' indicates that the being move and that the being's energy lowered&lt;br /&gt;
*All other returns indicate that the being did not move and that its energy did not decrease:&lt;br /&gt;
**'''1''' indicates that the being was stopped by a wall&lt;br /&gt;
**'''2''' indicates that the being was stopped by a door&lt;br /&gt;
**'''3''' indicates that the being was stopped by another being&lt;br /&gt;
&lt;br /&gt;
Specifically, when the movement process is interrupted, '''being:direct_seek()''' searches for CF_BLOCKMOVE. If it is not found on the blocking coordinate, '''3''' is returned; if CF_BLOCKMOVE is found but CF_OPENABLE is also found (which is used for doors), '''2''' is returned; in other cases when CF_BLOCKMOVE is found, '''1''' is returned.&lt;br /&gt;
&lt;br /&gt;
===being:path_find()===&lt;br /&gt;
'''being:path_find'''(''coord'',''scan_cutoff'',''scan_max'') searches for a series of coordinates for ''being'' to travel between its current position and ''coord'', using parameters ''scan_cutoff'' and ''scan_max'' to choose the best path. ''scan_cutoff'' and ''scan_max'' are a part of the pathing algorithm and higher numbers tend to be pretty intensive. As a standard, ''scan_cutoff'' is set to 10 for normal enemies and 40 for bosses, while ''scan_maximum'' is set to 40 for normal enemies and 200 for boss enemies.&lt;br /&gt;
&lt;br /&gt;
The return for this method determines whether or not a path was successfully found. Even if a complete path was not created, there will still be a path that '''being:path_find()''' established for ''being'', and can be used as a way to begin its approach to ''coord''.&lt;br /&gt;
&lt;br /&gt;
'''being:path_find()''' does not actually move the being, nor does it decrease energy: use '''being:path_next()''' in order to initiate the movement attempt.&lt;br /&gt;
&lt;br /&gt;
Generally speaking, it is not good practice to recalculate a pathing algorithm on every action, tempting as that may be. Naturally, the shuffling of enemies and opening/closing doors can affect whether or not the path is a correct one, but it is better to consider these exceptions as the time to call '''being:path_find()''', rather than doing so all the time.&lt;br /&gt;
&lt;br /&gt;
===being:path_next()===&lt;br /&gt;
'''being:path_next()''' command ''being'' to move to a coordinate as specified by '''being:path_find()'''. To think of this process abstractly, consider that whenever '''being:path_next()''' is executed, an array of steps is called: the first step is then used as the coordinate into which the being moves, and is removed from the array. Thus, calling the method each time moves the being to each coordinate, until the array is entirely removed and the being has reached the supposed target position.&lt;br /&gt;
&lt;br /&gt;
'''being:path_next()''' carries the same return values as '''being:direct_seek()''', and exceptions can be handled in the same manner.&lt;br /&gt;
&lt;br /&gt;
===being:attack()===&lt;br /&gt;
'''being:attack'''(''coord'') commands ''being'' to use its melee attack on ''coord''. If ''coord'' cannot be attacked within melee distance, or ''being'' cannot use its melee attack, the being's energy does not decrease.&lt;br /&gt;
&lt;br /&gt;
'''being:attack'''(''enemy'') commands ''being'' to use its melee attack on ''enemy'', another being. The same conditions for energy modification are used here.&lt;br /&gt;
&lt;br /&gt;
The output returns true in the event that the attack was successful (whether or not it dealt damage is independent) and false otherwise&lt;br /&gt;
&lt;br /&gt;
===being:fire()===&lt;br /&gt;
'''being:fire'''(''coord'',''weapon'') commands ''being'' fire its ''weapon'', aiming at ''coord''. If ''weapon'' cannot be fired (e.g., out of ammo), then the being's energy does not decrease.&lt;br /&gt;
&lt;br /&gt;
As there is no return value to determine whether or not the being's attack was successful, you may want to set up exceptions in the event that ''weapon'' cannot fire.&lt;br /&gt;
&lt;br /&gt;
===being:reload()===&lt;br /&gt;
'''being:reload()''' commands ''being'' to attempt to reload its currently-equipped weapon. If the weapon cannot be reloaded, then the being's energy does not decrease.&lt;br /&gt;
&lt;br /&gt;
The output returns true if the being reloaded the weapon and false otherwise. The reload can partially fill the weapon's ammo capacity depending on the ammo reserves of ''being'', and '''being:reload()''' will still return true.&lt;br /&gt;
&lt;br /&gt;
===being:wear()===&lt;br /&gt;
'''being:wear'''(''slot'') commands ''being'' to equip an item that exists in position ''slot'' of its inventory. (For instance, to equip the first item in the inventory, ''slot'' should be set to 1.) If the item in position ''slot'' cannot be equipped, or if the being cannot equip items, the being's energy does not decrease.&lt;br /&gt;
&lt;br /&gt;
'''being:wear'''(''item'') commands ''being'' to equip ''item'' from its inventory. ''being'' will always equip ''item'' from the lowest slot in its inventory. If ''item'' does not exist in the being's inventory, or if ''being'' cannot equip items, the being's energy does not decrease.&lt;br /&gt;
&lt;br /&gt;
The output returns true if the being equipped an item and false otherwise.&lt;br /&gt;
&lt;br /&gt;
===being:use()===&lt;br /&gt;
'''being:use'''(''slot'') commands ''being'' to use the item that exists in position ''slot'' of its inventory. If the item in position ''slot'' cannot be used in any way, the being's energy does not decrease.&lt;br /&gt;
&lt;br /&gt;
'''being:use'''(''item'') commands ''being'' to use ''item'' from its inventory. ''being'' will always use ''item'' from the lowest slot in its inventory. If ''item'' does not exist in the being's inventory, or if cannot be used in any way, the being's energy does not decrease.&lt;br /&gt;
&lt;br /&gt;
Currently there is a bug that causes the output of this method to always return false, so it is useless to return.&lt;br /&gt;
&lt;br /&gt;
===being:pickup()===&lt;br /&gt;
'''being:pickup()''' commands ''being'' to pick up an item at the same position as ''being''. If there is no item to pick up, or if ''being'' cannot pick up items, the being's energy does not decrease.&lt;br /&gt;
&lt;br /&gt;
'''being:pickup'''(''coord'') commands ''being'' to pick up an item at ''coord'' from where it is standing. The same condition for energy modification is used here.&lt;br /&gt;
&lt;br /&gt;
The output returns true if the being picked up an item and false otherwise.&lt;br /&gt;
&lt;br /&gt;
==Single-minded AI==&lt;br /&gt;
A single-minded AI never needs to make an intelligent decision between two choices. Simply put, it follows only action-based algorithms: if there are changes that do not stem from actions, they are automatic or constant. Such AI are the easiest to create and implement, as their movements are always obvious when observed. There are two ways to implement a single-minded AI: create only single state that performs the actions, or divide each type of action into its own state and cycle through them. Most of the time a single state is all that is necessary, though there can be cases in which having separate states is a more logical procedure.&lt;br /&gt;
&lt;br /&gt;
We will now return to our example AI from before, which involved either walking up or stopping whenever walking would cause it to hit a solid object. It is a sufficient AI but is certainly lacking in mobility: after all, the game will eventually run out of coordinates if it can only move in a single direction. Let us expand on the design by allowing it to move in any orthogonal direction (up, down, left, or right), depending on what direction it is currently walking and what is in the way.&lt;br /&gt;
&lt;br /&gt;
We should begin by setting up the AI such that it can walk in all of the directions specified. Since each direction can be considered a separate action, you may be tempted to create a state for each one, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
AI{&lt;br /&gt;
    name = &amp;quot;walk_ai&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    OnCreate = function(self)&lt;br /&gt;
        self:add_property(&amp;quot;ai_state&amp;quot;,&amp;quot;walk_up&amp;quot;)&lt;br /&gt;
    end,&lt;br /&gt;
&lt;br /&gt;
    states = {&lt;br /&gt;
        walk_up = function(self)&lt;br /&gt;
            local up_coord = self:get_position() + coord.new(0,-1)&lt;br /&gt;
            if self:direct_seek(up_coord) ~= 0 then&lt;br /&gt;
                self.scount = self.scount - 1000&lt;br /&gt;
                return(&amp;quot;walk_right&amp;quot;)&lt;br /&gt;
            end&lt;br /&gt;
        end,&lt;br /&gt;
&lt;br /&gt;
        walk_right = function(self)&lt;br /&gt;
            local right_coord = self:get_position() + coord.new(1,0)&lt;br /&gt;
            if self:direct_seek(right_coord) ~= 0 then&lt;br /&gt;
                self.scount = self.scount - 1000&lt;br /&gt;
                return(&amp;quot;walk_down&amp;quot;)&lt;br /&gt;
            end&lt;br /&gt;
        end,&lt;br /&gt;
&lt;br /&gt;
        walk_down = function(self)&lt;br /&gt;
            local down_coord = self:get_position() + coord.new(0,1)&lt;br /&gt;
            if self:direct_seek(down_coord) ~= 0 then&lt;br /&gt;
                self.scount = self.scount - 1000&lt;br /&gt;
                return(&amp;quot;walk_left&amp;quot;)&lt;br /&gt;
            end&lt;br /&gt;
        end,&lt;br /&gt;
&lt;br /&gt;
        walk_left = function(self)&lt;br /&gt;
            local down_coord = self:get_position() + coord.new(-1,0)&lt;br /&gt;
            if self:direct_seek(down_coord) ~= 0 then&lt;br /&gt;
                self.scount = self.scount - 1000&lt;br /&gt;
                return(&amp;quot;walk_up&amp;quot;)&lt;br /&gt;
            end&lt;br /&gt;
        end,&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This acts much like the original example, except that we have four states that the being cycles through: each time the being runs into a solid object, in addition to waiting, it will move to another state, which will be accessed on the next action. For most programmers this setup looks horribly inefficient, since it is a lot of copy-pasting with only a couple of changes per copy. There is a far more elegant way to set up the four directions using what is called a lookup table:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
AI{&lt;br /&gt;
    name = &amp;quot;walk_ai&amp;quot;,&lt;br /&gt;
    &lt;br /&gt;
    OnCreate = function(self)&lt;br /&gt;
        self:add_property(&amp;quot;ai_state&amp;quot;,&amp;quot;walk&amp;quot;)&lt;br /&gt;
        self:add_property(&amp;quot;walk_num&amp;quot;,1)&lt;br /&gt;
    end,&lt;br /&gt;
&lt;br /&gt;
    states = {&lt;br /&gt;
        walk = function(self)&lt;br /&gt;
            local c = self:get_position()&lt;br /&gt;
            local coord_list = {c+coord.new(0,-1), --up    (1)&lt;br /&gt;
                                c+coord.new(1, 0), --right (2)&lt;br /&gt;
                                c+coord.new(0, 1), --down  (3)&lt;br /&gt;
                                c+coord.new(-1,0)} --left  (4)&lt;br /&gt;
            --attempt to move&lt;br /&gt;
            if self:direct_seek(coord_list[self.walk_num]) ~= 0 then&lt;br /&gt;
                --on failure, wait and turn clockwise&lt;br /&gt;
                self.scount = self.scount - 1000&lt;br /&gt;
                self.walk_num = math.fmod(self.walk_num,4)+1&lt;br /&gt;
            end&lt;br /&gt;
        end,&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lookup table is an array that contains a number of elements are necessarily hard-coded and conveniently organized for reference. The code doesn't know what a direction is until we explicitly express it somewhere: a convenient shortcut is to use a lookup table and simply call a certain element that we know to be of a certain definition. In some cases lookup tables are placed independently in separate functions for conversion purposes. Here we create a dynamic lookup table (since it changes every time the being's position does) that determines each movement coordinate in the orthogonal directions.&lt;br /&gt;
&lt;br /&gt;
In order to make use of the table, we need a variable that keeps track of the being's current direction it wants to move: this is done by adding a property called ''walk_num'', which is an integer representing a coordinate from the lookup table. '''self:direct_seek'''(''coord_list''['''self'''.''walk_num'']) will now move the being based on the value of ''walk_num'' (comments in the example show the number-direction correlation).&lt;br /&gt;
&lt;br /&gt;
When the being runs into a solid object, in addition to waiting, ''walk_num'' is incremented by one on a modulo-four cycle using the '''math.fmod()''' method. '''math.fmod'''(''divisor'',''dividend'') divides ''divisor'' by ''dividend'' and returns the remainder of the quotient (e.g., 7 / 4 = 1R3; math.fmod(7,4) returns 3). With each use of the cycling line of code, ''walk_num'' increases by one, and whenever it was equal to four, it is set back to one again (as '''math.fmod'''(4,4)+1 == 0+1 == 1).&lt;br /&gt;
&lt;br /&gt;
This new state is functionally identical to the four-state case but is easily half its size in terms of lines of code. Finding ways to cut down on the magnitude of a script can greatly improve the ability to debug it, as well as allowing others to read and understand it. Since states can become very complicated, it is important to organize them as cleanly as possible.&lt;br /&gt;
&lt;br /&gt;
Suppose we want this being to be able to attack the player whenever they get in its path. It is easy to include this in the AI we already have:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
AI{&lt;br /&gt;
    name = &amp;quot;bulldozer_ai&amp;quot;,&lt;br /&gt;
    &lt;br /&gt;
    OnCreate = function(self)&lt;br /&gt;
        self:add_property(&amp;quot;ai_state&amp;quot;,&amp;quot;walk&amp;quot;)&lt;br /&gt;
        self:add_property(&amp;quot;walk_num&amp;quot;,1)&lt;br /&gt;
    end,&lt;br /&gt;
&lt;br /&gt;
    states = {&lt;br /&gt;
        walk = function(self)&lt;br /&gt;
            local c = self:get_position()&lt;br /&gt;
            local coord_list = {c+coord.new(0,-1), --up    (1)&lt;br /&gt;
                                c+coord.new(1, 0), --right (2)&lt;br /&gt;
                                c+coord.new(0, 1), --down  (3)&lt;br /&gt;
                                c+coord.new(-1,0)} --left  (4)&lt;br /&gt;
            --attempt to move&lt;br /&gt;
            local move_to = coord_list[self.walk_num]&lt;br /&gt;
            if self:direct_seek(move_to) ~= 0 then&lt;br /&gt;
                --if player is in the way, attack them&lt;br /&gt;
                if move_to == player:get_position() then&lt;br /&gt;
                    self:attack(move_to)&lt;br /&gt;
                --otherwise, wait and turn clockwise&lt;br /&gt;
                else&lt;br /&gt;
                    self.scount = self.scount - 1000&lt;br /&gt;
                    self.walk_num = math.fmod(self.walk_num,4)+1&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end,&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First, we define ''move_to'' as the coordinate where the being attempts to move: this is done to make the code easier to read through, since the coordinate will now be referenced multiple times. Next, after knowing that '''self:direct_seek()''' failed, we include a splitting:&lt;br /&gt;
*If ''move_to'' is equal to the player's current position, use '''self:attack()''' to attack the player.&lt;br /&gt;
*Otherwise, we do what was done before (wait a second and continue the directional cycling)&lt;br /&gt;
&lt;br /&gt;
One could say that this borders on an intelligent decision made by the AI, but it is a very basic one and doesn't do anything other than include a special case in which the being is blocked by the player. Compared to what AI can eventually develop into, this is still an extremely simple example.&lt;br /&gt;
&lt;br /&gt;
A truly single-minded AI that attacks would look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
AI{&lt;br /&gt;
    name = &amp;quot;attack_ai&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    OnCreate = function(self)&lt;br /&gt;
        self:add_property(&amp;quot;ai_state&amp;quot;, &amp;quot;attack&amp;quot;)&lt;br /&gt;
    end,&lt;br /&gt;
&lt;br /&gt;
    states = {&lt;br /&gt;
        attack = function(self)&lt;br /&gt;
            local p = player:get_position()&lt;br /&gt;
            if not self:fire(p, self.eq.weapon) then&lt;br /&gt;
                if not self:attack(p) then&lt;br /&gt;
                    self.scount = self.scount - 1000&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end,&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First, we set ''p'' as the player's coordinate. The being then tries to fire a ranged attack at ''p''. If it cannot (either because the being has no ranged weapon or that weapon is out of ammo) then it will attempt a melee attack on ''p''. If it cannot execute the melee attack, it will simply wait. Such a being, with a ranged attack, will attempt to kill the player from anywhere on the map: after all, it lacks the intelligence to know whether or not it can see the player.&lt;br /&gt;
&lt;br /&gt;
Single-minded AI are simple, but they lack the ability to give the player an intelligent challenge with respect to a being using it. Most modders will want to create AI that make decisions based on the whereabouts of various objects on the map, or the being's state, or even global timers. These require a more rigorous approach to ensure that they are produced without flaw.&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Modding:Tutorial/The_Infinite_Arena</id>
		<title>Modding:Tutorial/The Infinite Arena</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Modding:Tutorial/The_Infinite_Arena"/>
				<updated>2025-08-11T12:29:27Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(NOTE: if you are unfamiliar with the general structure of the Hell's Arena module, it is suggested that you [[Modding:Tutorial/Recreating_Hell's_Arena|read the tutorial]] before proceeding, as many of the topics found there also are here, and will only be touched upon in this tutorial.)&lt;br /&gt;
&lt;br /&gt;
[[Hell's Arena]] is a fun little level, as it can be fairly difficult to complete without some grasp on DRL's mechanics, but pillar and monster placement aside, it is still a fairly static map. The following tutorial is a generalized version of Hell's Arena, coined the Infinite Arena, which has been reconstructed based on [[User:Yaflhdztioxo|yaflhdztioxo's]] design from v0.9.9.1. A fair number of seemingly-superfluous tools have also been created as a means to provide easy customization possibilities for those who want to quickly change the settings of the Arena. If nothing else, you will discover a variety of helper tools in this tutorial that may prove to be useful in your own modules.&lt;br /&gt;
&lt;br /&gt;
==Special Concept: Custom Tables and Functions==&lt;br /&gt;
The basics of tables have already been explained in the [[Modding:Tutorial/Game Objects|Game Objects]] tutorial: it was also explained there that building your own tables is generally unnecessary. There are, however, plenty of reasons to make tables for your own purposes:&lt;br /&gt;
&lt;br /&gt;
*You want the game to randomly choose from a group of variables&lt;br /&gt;
*You want to perform calculations or subroutines on many objects simultaneously&lt;br /&gt;
*You are creating an object map that other functions may require (e.g., translation table for .run() )&lt;br /&gt;
*You want to store a number of variables in an organized manner in order to access them easily&lt;br /&gt;
&lt;br /&gt;
There are two kinds of tables. The first kind are what are more commonly referred to as tables, as they contain keys and values in each of their fields:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local some_table = {&lt;br /&gt;
    key1 = &amp;quot;value1&amp;quot;,&lt;br /&gt;
    key2 = &amp;quot;value2&amp;quot;,&lt;br /&gt;
    ....&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In fact, these tables can contain more tables, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local big_table = {&lt;br /&gt;
    small_table1 = {&lt;br /&gt;
        key1 = &amp;quot;value1&amp;quot;,&lt;br /&gt;
        key2 = &amp;quot;value2&amp;quot;,&lt;br /&gt;
    },&lt;br /&gt;
    small_table2 = {&lt;br /&gt;
        key1 = &amp;quot;value3&amp;quot;,&lt;br /&gt;
        key3 = &amp;quot;value4&amp;quot;,&lt;br /&gt;
    },&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that these sub-tables do not have to carry the same information, although you may want them to (depending on the table's purpose). In doing so, you can create very large and intricate tables to suit your needs.&lt;br /&gt;
&lt;br /&gt;
The second kind of table is commonly known in the modding community as an array, and is essentially a table that does not explicitly write keys in each field. The following examples show an array, followed by a table that imitates the functionality of an array:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local some_array = {&amp;quot;value1&amp;quot;,&amp;quot;value2&amp;quot;,&amp;quot;value3&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
local some_imit_table = {&lt;br /&gt;
    [1] = &amp;quot;value1&amp;quot;,&lt;br /&gt;
    [2] = &amp;quot;value2&amp;quot;,&lt;br /&gt;
    [3] = &amp;quot;value3&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local big_array = {&lt;br /&gt;
    {&amp;quot;value1&amp;quot;,&amp;quot;value2&amp;quot;,&amp;quot;value3&amp;quot;},&lt;br /&gt;
    {&amp;quot;value4&amp;quot;,&amp;quot;value5&amp;quot;,&amp;quot;value6&amp;quot;},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local big_imit_table = {&lt;br /&gt;
    [1] = {&lt;br /&gt;
        [1] = &amp;quot;value1&amp;quot;,&lt;br /&gt;
        [2] = &amp;quot;value2&amp;quot;,&lt;br /&gt;
        [3] = &amp;quot;value3&amp;quot;,&lt;br /&gt;
    },&lt;br /&gt;
    [2] = {&lt;br /&gt;
        [1] = &amp;quot;value4&amp;quot;,&lt;br /&gt;
        [2] = &amp;quot;value5&amp;quot;,&lt;br /&gt;
        [3] = &amp;quot;value6&amp;quot;,&lt;br /&gt;
    }, &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, the array format is a lot more compact, but it also forces very specific keys on each field (namely numerical ones). Naturally, tables and arrays can be combined seamlessly, such that you can have a table of arrays or an array or tables (as well as more complicated setups).&lt;br /&gt;
&lt;br /&gt;
When you want to call various parts within a table or array, you can use the following syntax (we will base these on ''big_array'' and ''big_table''):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
big_table.small_table1        --returns the contents of small_table1&lt;br /&gt;
big_table[small_table1]       --identical to above&lt;br /&gt;
&lt;br /&gt;
big_table.small_table1.key1   --returns &amp;quot;value1&amp;quot;&lt;br /&gt;
big_table.small_table1[key1]  --identical to above&lt;br /&gt;
big_table[small_table1].key1  --identical to above&lt;br /&gt;
big_table[small_table1][key1] --identical to above&lt;br /&gt;
&lt;br /&gt;
big_array.1     --returns the contents of the first array in big_array&lt;br /&gt;
big_array[1]    --identical to above&lt;br /&gt;
&lt;br /&gt;
big_array.2.2   --returns &amp;quot;value5&amp;quot;&lt;br /&gt;
big_array.2[2]  --identical to above&lt;br /&gt;
big_array[2].2  --identical to above&lt;br /&gt;
big_array[2][2] --identical to above&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a matter of convention, we will write table-like extensions using the dot syntax and array-like extensions using the bracket syntax. (This is typically how other languages write their arrays and tables, and it is often a good idea to organize your code in such a manner so that it is easier to read when looking back at it.)&lt;br /&gt;
&lt;br /&gt;
Functions, like tables, are mostly known based on using parts of pre-defined object classes: in the case of functions, we should already be fairly familiar with their capabilities when calling engine hooks and API methods. The creation of a function is very simple, nearly identical to engine hooks.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local function sum_diff(arg1,arg2)&lt;br /&gt;
    val1 = arg1+arg2&lt;br /&gt;
    val2 = arg1-arg2&lt;br /&gt;
    return(val1,val2)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local add_diff = function(arg1,arg2) --this line is identical to the first line of the above function&lt;br /&gt;
    ....&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*First you must give the function a name: the above example is called '''sum_diff()'''.&lt;br /&gt;
*Next you must supply input arguments, if any. These are variables that can be used within the function, which is otherwise self-contained. That is to say, a function can't use any variables from anywhere else in your lua script unless they are given through the input arguments. The above example takes in two arguments, generically named ''arg1'' and ''arg2''.&lt;br /&gt;
*From here we add the script that is to be run when the function is called (this is usually what you concern yourself with when working with the engine hooks). In the above example, the sum of ''arg1'' and ''arg2'' is assigned to ''val1'', and their difference is assigned to ''val2''.&lt;br /&gt;
*Finally, we consider what the function should output. This can be accomplished in two ways when modding:&lt;br /&gt;
**You can simply provide outputs to the function using the return() core method. This immediately stops the function and sends outputs to the line that called the function. In the above example, ''val1'' and ''val2'' are returned. (Note that, when called, the script should contain some variables so that the return values are properly assigned.)&lt;br /&gt;
**You can manipulate objects. Since changing objects (such as their prototype) modify things on the engine side of the game, this can be done without having any particular outputs to the function. Even though the function is self-contained within your script, it can influence things not belonging to the script.&lt;br /&gt;
&lt;br /&gt;
If you want to call a function, use its name with the appropriate input and outputs. For the above example, you could call the function in the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local num1 = 5&lt;br /&gt;
local num2 = 4&lt;br /&gt;
&lt;br /&gt;
local sum,diff = sum_diff(num1,num2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ''sum'' variable will have a value of 9, and the ''diff'' variable will have a value of 1.&lt;br /&gt;
&lt;br /&gt;
In the Infinite Arena module, a large portion of the code is dedicated to constructing easy-to-read and well-organized tables, as well as functions that make use of them. The tables and functions will eventually be called in the engine hooks, which leaves us with a relatively small amount of run-time code to sift through. Ideally, modules should have a format in which much of the script is written not as a part of the core module, but as something that the core module will refer to.&lt;br /&gt;
&lt;br /&gt;
==Initialization Code==&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
&lt;br /&gt;
====mobGenStats====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--customize min_lev/max_lev/weight of each enemy (defaults given)&lt;br /&gt;
--for names of beings, check Object IDs in the modding documentation&lt;br /&gt;
--be aware that JC auto-ends the game unless modified directly&lt;br /&gt;
local mobGenStats = {&lt;br /&gt;
    { being = &amp;quot;former&amp;quot;,         min_lev = 0,   max_lev = 12,  weight = 10 },&lt;br /&gt;
    { being = &amp;quot;sergeant&amp;quot;,       min_lev = 2,   max_lev = 15,  weight = 10 },&lt;br /&gt;
    { being = &amp;quot;captain&amp;quot;,        min_lev = 8,   max_lev = 15,  weight = 10 },&lt;br /&gt;
    ....&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''mobGenStats'' is an array of tables: each table contains four fields relating to the being prototype. In each case, a being's identifier ''being'' is given, followed by a ''min_lev'', ''max_lev'', and ''weight'' (all generation parameters). The purpose of ''mobGenStats'' is to switch particular values for others in the being prototypes that already exist. Normally this can be done for a particular enemy with the following line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
beings.former.weight = 0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would change the ''weight'' key in the ''former'' table of the ''beings'' array (which holds all being prototypes) to zero, thereby removing the possibility of former humans appearing through standard generation procedures. However, if a modder wants to change many parameters at once, they can use what is done in the Infinite Arena. First is the creation of the above table, and then you use the table in a for loop as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--changes the generation stats of enemies based on mobGenStats&lt;br /&gt;
for _,v in ipairs(mobGenStats) do&lt;br /&gt;
    beings[v.being].min_lev = v.min_lev&lt;br /&gt;
    beings[v.being].max_lev = v.max_lev&lt;br /&gt;
    beings[v.being].weight = v.weight&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The conditional statement 'for a,b  in ipairs(array)' breaks down in the following way:&lt;br /&gt;
*''a'' is the iterator of the for loop itself (whenever the code repeats, ''a'' increases by one)&lt;br /&gt;
**As we have no need for a basic iterator, we leave it blank using an underscore.&lt;br /&gt;
*''b'' is the array iterator (directly calls the particular array, similarly increments)&lt;br /&gt;
*in '''ipairs()''' tells the for loop to iterate through values in an array&lt;br /&gt;
*''array'' is the array in question&lt;br /&gt;
&lt;br /&gt;
In this particular case, the loop iterates through each array and sets the being's ''min_lev'', ''max_lev'', and ''weight'' (as found in the being prototype) to the values as determined by ''mobGenStats''. ''v.being'' is the same as a being's identifier from ''mobGenStats'', which is how the loop iterates through all being prototypes. In this way all of the beings in the prototype array can be changed quickly without a bunch of lines specifying each key and value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--enemy scaling for each wave: note that game difficulty will modify scaling independently&lt;br /&gt;
local mob_scale_factor = 0.5&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, we have a variable that indicates the initial scaling of enemies. For the Infinite Arena, using the base game's scaling is probably too difficult for what a player at a given difficulty would expect, so it is cut in half by default.&lt;br /&gt;
&lt;br /&gt;
====itemGenStats====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--customize level/weight of items (defaults given)&lt;br /&gt;
--for names of items, check Object IDs in the modding documentation&lt;br /&gt;
local itemGenStats = {&lt;br /&gt;
    --Commons&lt;br /&gt;
    &lt;br /&gt;
    --weapons&lt;br /&gt;
    { item = &amp;quot;knife&amp;quot;,        level = 1,  weight = 640 },&lt;br /&gt;
    { item = &amp;quot;pistol&amp;quot;,       level = 1,  weight = 70  },&lt;br /&gt;
    { item = &amp;quot;shotgun&amp;quot;,      level = 2,  weight = 180 },&lt;br /&gt;
    ....&lt;br /&gt;
    --ammo/ammo packs&lt;br /&gt;
    ....&lt;br /&gt;
    --armor/boots&lt;br /&gt;
    ....&lt;br /&gt;
    --consumables&lt;br /&gt;
    ....&lt;br /&gt;
    --powerups&lt;br /&gt;
    ....    &lt;br /&gt;
    --Exotics&lt;br /&gt;
    ....    &lt;br /&gt;
    --Uniques&lt;br /&gt;
    ....    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''itemGenStats'' is just like ''mobGenStats'', except that it is an array of tables regarding generation parameters for items. Note that ''mobGenStats'' and ''itemGenStats'' in the source set all of the monsters and items to their default settings, so there will be no difference between the generation in the base game and in the Infinite Arena unless the modder chooses to customize it personally. (''mobGenStats'' and ''itemGenStats'' are also shortened here: see Review for the full arrays.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--changes the generation stats of items based on itemGenStats&lt;br /&gt;
for _,v in ipairs(itemGenStats) do&lt;br /&gt;
    items[v.item].level  = v.level&lt;br /&gt;
    items[v.item].weight = v.weight&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As with ''mobGenStats'', a for loop is used to run through all of the variables in the ''itemGenStats'' tables and change the prototypes to anything that the modder wishes to customize.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--item scaling for each wave&lt;br /&gt;
local item_scale_factor = 0.5&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The item scaling is also dropped to scale properly with the drop in monster scaling. (Feel free to change these around for your own amusement, of course.)&lt;br /&gt;
&lt;br /&gt;
====anncrMsg and crowdMsg====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--add your own announcer lines here&lt;br /&gt;
local anncrMsg = {&lt;br /&gt;
    --displays whenever player completes wave&lt;br /&gt;
    success = {&lt;br /&gt;
        {&lt;br /&gt;
        &amp;quot;The voice booms, \&amp;quot;Congratulations mortal!&amp;quot;,&lt;br /&gt;
        &amp;quot;The voice booms, \&amp;quot;Impressive mortal!&amp;quot;,&lt;br /&gt;
        &amp;quot;The voice booms, \&amp;quot;Most impressive.&amp;quot;,&lt;br /&gt;
        &amp;quot;The voice booms, \&amp;quot;You are a formidable warrior!&amp;quot;,&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
        ....&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
        ....&lt;br /&gt;
        }&lt;br /&gt;
    },&lt;br /&gt;
    --displays whenever player decides to continue to another wave&lt;br /&gt;
    choice = {&lt;br /&gt;
    ....&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''anncrMsg'' is the opposite of the generation variables: it is a table of arrays. There are two arrays within ''anncrMsg'' labeled ''success'' and ''choice'', each of which carry their own groups of variables. ''anncrMsg'' itself is called whenever the announcer displays a message (after the third wave), using either ''success'' (whenever the player completes the wave) or ''choose'' (whenever the player chooses to continue to the next wave). Since each group of strings should be handled separately, they are grouped separately, hence the need for a table of arrays.&lt;br /&gt;
&lt;br /&gt;
In addition, ''anncrMsg.success'' and ''anncrMsg.choose'' are an array of arrays themselves. The reason for this will be explained in '''build_announcerMsg()'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--add your own crowd lines here&lt;br /&gt;
--displays whenever enemy is killed&lt;br /&gt;
local crowdMsg = {&lt;br /&gt;
    &amp;quot;The crowd goes wild! \&amp;quot;BLOOD! BLOOD!\&amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;The crowd cheers! \&amp;quot;Blood! Blood!\&amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;The crowd cheers! \&amp;quot;Kill! Kill!\&amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;The crowd hisses. \&amp;quot;We came for a REAL fight!\&amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;The crowd boos. \&amp;quot;No skill, no kill!\&amp;quot;&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By contrast, ''crowdMsg'' is a simple array of strings, called whenever a crowd message is necessary. Since the crowd only needs to be called in one case, only one group of strings is initialized, and so a table of arrays is no longer required.&lt;br /&gt;
&lt;br /&gt;
===Functions===&lt;br /&gt;
&lt;br /&gt;
====build_gear()====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--changes player equipment&lt;br /&gt;
--add &amp;quot;nil&amp;quot; for any slot that should be empty&lt;br /&gt;
--always refreshes all slots: do not use to change only one equipment slot&lt;br /&gt;
local function build_gear(weap,prep,body,foot)&lt;br /&gt;
    player.eq:clear()&lt;br /&gt;
    if weap then player.eq.weapon   = item.new(weap) end --main weapon&lt;br /&gt;
    if prep then player.eq.prepared = item.new(prep) end --prepared weapon	&lt;br /&gt;
    if body then player.eq.armor    = item.new(body) end --body armor&lt;br /&gt;
    if foot then player.eq.boots    = item.new(foot) end --boots&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''build_gear()''' is an example of a &amp;quot;helper function&amp;quot;, as it runs a procedure that could easily be reproduced in the run-time code but simplifies the input whenever the code needs to be modified. In this case, the function clears all of the player's equipment and potentially adds a new item in each slot. There are four inputs, each corresponding to a particular slot: if the value in an input argument is not nil, it then adds a new item to that player's equipment slot.&lt;br /&gt;
&lt;br /&gt;
In the run-time code, the player need only change the input variables rather than changing several lines. This may not appear very necessary for '''build_gear()''' but the concept of a helper function can make modifications to code much easier.&lt;br /&gt;
&lt;br /&gt;
====build_pack()====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--changes player inventory&lt;br /&gt;
--always refreshes all slots: do not use to change only one equipment slot&lt;br /&gt;
local function build_pack(itemPack)&lt;br /&gt;
    player.inv:clear()&lt;br /&gt;
    for _,part in ipairs(itemPack) do&lt;br /&gt;
        if items[part.name].type == ITEMTYPE_AMMO then&lt;br /&gt;
            --ammo is handled separately, loops for however many stacks are needed&lt;br /&gt;
            for n=1,math.ceil(part.amt/items[part.name].ammomax) do&lt;br /&gt;
                local pack = item.new(part.name)&lt;br /&gt;
                if part.amt &amp;lt; pack.ammomax then&lt;br /&gt;
                    --remainder (or single) stack&lt;br /&gt;
                    pack.ammo = part.amt&lt;br /&gt;
                else&lt;br /&gt;
                    --filled (and/or multiple) stacks&lt;br /&gt;
                    pack.ammo = pack.ammomax&lt;br /&gt;
                    part.amt = part.amt - pack.ammomax&lt;br /&gt;
                end&lt;br /&gt;
                player.inv:add(pack)&lt;br /&gt;
            end&lt;br /&gt;
        else&lt;br /&gt;
            --loops for however many items are needed&lt;br /&gt;
            for n=1,part.amt do&lt;br /&gt;
                player.inv:add(part.name)&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''build_pack()''' is another helper function, this time clearing the inventory of the player and adding in new items there. It uses the &amp;quot;in '''ipairs()'''&amp;quot; iteration method to check all variables in an array in the following way:&lt;br /&gt;
&lt;br /&gt;
*if the item's ''type'' is ITEMTYPE_AMMO:&lt;br /&gt;
**a new for loop is run, iterating from 1 to ''ammonum''/''ammomax'' for the specific ammo (''ammonum'' currently being how much that the player's inventory receives)&lt;br /&gt;
**first, the new ammo stack is created&lt;br /&gt;
**if ''ammonum'' is less than the ammo's ''ammomax'':&lt;br /&gt;
***set the ammo stack equal to ''ammonum''&lt;br /&gt;
**otherwise:&lt;br /&gt;
***set the ammo stack equal to ''ammomax''&lt;br /&gt;
***subtract ''ammonum'' by ''ammomax''&lt;br /&gt;
**finally, add the ammo stack to the player's inventory (and this process repeats as necessary)&lt;br /&gt;
*if the item's ''type'' is not ITEMTYPE_AMMO:&lt;br /&gt;
**a new for loop is run, iterating as many times as items should be added for the particular item in question&lt;br /&gt;
**the item(s) are then added to the player's inventory, one by one&lt;br /&gt;
&lt;br /&gt;
The input requires an array of tables, although the format is rather simple. Here is an example of an input for '''build_pack()''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local itemPack = {&lt;br /&gt;
    {name = &amp;quot;chaingun&amp;quot;, amt = 1  }&lt;br /&gt;
    {name = &amp;quot;ammo&amp;quot;,     amt = 360}&lt;br /&gt;
    {name = &amp;quot;smed&amp;quot;,     amt = 5  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each table in the array requires only two fields: ''name'', which corresponds to the item's identifier, and ''amt'', which specifies how many of that item should be added. In the case of ammunition, the amount of ammo should be specified instead, as it is handled uniquely in order to produce an ideal number of stacks. The above example would add one chaingun, three 9mm ammo (x100) stacks, one 9mm ammo (x60) stack, and five small med-packs to the player's inventory. Keep in mind that the player can only hold 22 items, and any items added after 22 items have been added to the inventory will be disregarded.&lt;br /&gt;
&lt;br /&gt;
====build_announcerMsg()====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local function build_announcerMsg(MSG)&lt;br /&gt;
    for _,msgNum in ipairs(MSG) do&lt;br /&gt;
        ui.msg(table.random_pick(msgNum))&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''build_announcerMsg()''' function iterates through an array and selects a random index from a table within the array. The purpose of this simple function is to loop through a series of arrayed strings from ''anncrMsg'' and randomly pick strings from those arrays. '''build_announcerMsg'''(''anncrMsg.success'') sets up three random messages from each array in its array, and '''build_announcerMsg'''(''anncrMsg.choose'') sets up two random messages from each array in its array. (Setting up a lot of tables within tables can be confusing, but it becomes relatively simple as a means to organize variables together when compared to keeping track of each variable separately.)&lt;br /&gt;
&lt;br /&gt;
====get_corpses() and clear_corpses()====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--initializes table of cells that only contains corpses&lt;br /&gt;
local corpseCells = {}&lt;br /&gt;
&lt;br /&gt;
local function get_corpses()&lt;br /&gt;
    for i = 1, #cells do&lt;br /&gt;
        if cells[i] and cells[i].flags then&lt;br /&gt;
            if cells[i].flag_set[CF_CORPSE] == true then&lt;br /&gt;
                table.insert(corpseCells, i) --i == sID's numeric value&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''get_corpses()''' is a quick function that creates a table, ''corpseCells'', and loops through all cells in the cell prototype array, selecting only those that contain the CF_CORPSE flag (indicating that the cell acts like a corpse) and adding it to ''corpseCells''. This method is often the most effective way to create a selective table of objects.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--removes corpses and blood-like cells&lt;br /&gt;
local function clear_corpses()&lt;br /&gt;
    --fade away all blood&lt;br /&gt;
    Generator.transmute(&amp;quot;blood&amp;quot;, &amp;quot;floor&amp;quot;)&lt;br /&gt;
    Generator.transmute(&amp;quot;bloodpool&amp;quot;, &amp;quot;blood&amp;quot;)&lt;br /&gt;
    --changes corpses to blood&lt;br /&gt;
    for i = 1, #corpseCells do&lt;br /&gt;
        Generator.transmute(corpseCells[i], &amp;quot;bloodpool&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''clear_corpses()'' puts our table of corpses to use by transmuting any cells contained in the table into the &amp;quot;bloodpool&amp;quot; cell. Additionally, all blood pools are changed to &amp;quot;blood&amp;quot; and all blood is changed to &amp;quot;floor&amp;quot;. This is added to the Infinite Arena so that a ridiculous number of corpses isn't around when Arch-vile enemies begin to show themselves.&lt;br /&gt;
&lt;br /&gt;
==Engine Hooks==&lt;br /&gt;
&lt;br /&gt;
===.run()===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--Creation of Infinite Arena&lt;br /&gt;
function inf_arena.run()&lt;br /&gt;
    Level.name = &amp;quot;Infinite Arena&amp;quot;&lt;br /&gt;
    Level.name_number = 0&lt;br /&gt;
    Level.fill(&amp;quot;rwall&amp;quot;)&lt;br /&gt;
    Generator.set_permanence(area.FULL)&lt;br /&gt;
    &lt;br /&gt;
    local translation = {&lt;br /&gt;
    [&amp;quot;.&amp;quot;] = &amp;quot;floor&amp;quot;,&lt;br /&gt;
    [&amp;quot;#&amp;quot;] = {&amp;quot;rwall&amp;quot;, LFPERMANENT = true},&lt;br /&gt;
    [&amp;quot;X&amp;quot;] = &amp;quot;rwall&amp;quot;,&lt;br /&gt;
    [&amp;quot;,&amp;quot;] = &amp;quot;blood&amp;quot;,&lt;br /&gt;
    [&amp;quot;&amp;gt;&amp;quot;] = &amp;quot;stairs&amp;quot;,&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    local map = [[&lt;br /&gt;
#######################.............................########################&lt;br /&gt;
###########.....................................................############&lt;br /&gt;
#####..................................................................#####&lt;br /&gt;
##........................................................................##&lt;br /&gt;
#..........................................................................#&lt;br /&gt;
....,.......................................................................&lt;br /&gt;
.................................,...,......................................&lt;br /&gt;
.,.....................................,....................................&lt;br /&gt;
..,&amp;gt;.,..........................,...........................................&lt;br /&gt;
.,..,.................................,.,...................................&lt;br /&gt;
................................,..,...,....................................&lt;br /&gt;
............................................................................&lt;br /&gt;
............................................................................&lt;br /&gt;
#..........................................................................#&lt;br /&gt;
##........................................................................##&lt;br /&gt;
#####..................................................................#####&lt;br /&gt;
###########.....................................................############&lt;br /&gt;
#######################.............................########################&lt;br /&gt;
]]&lt;br /&gt;
    --change up the column types&lt;br /&gt;
    local column = {&lt;br /&gt;
    [[&lt;br /&gt;
,..,.,&lt;br /&gt;
,XXXX.&lt;br /&gt;
.X##X,&lt;br /&gt;
.XXXX.&lt;br /&gt;
,..,.,&lt;br /&gt;
    ]],&lt;br /&gt;
    [[&lt;br /&gt;
,..,.,&lt;br /&gt;
,X##X.&lt;br /&gt;
.####,&lt;br /&gt;
.X##X.&lt;br /&gt;
,..,.,&lt;br /&gt;
    ]],&lt;br /&gt;
    [[&lt;br /&gt;
,..,.,&lt;br /&gt;
,####.&lt;br /&gt;
.####,&lt;br /&gt;
.####.&lt;br /&gt;
,..,.,&lt;br /&gt;
    ]]&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    Level.place_tile(translation,map,2,2)&lt;br /&gt;
    for i=1,11 + math.random(4) do&lt;br /&gt;
        Level.scatter_put( area.new(5,3,68,15), translation, table.random_pick(column), &amp;quot;floor&amp;quot;, 1)&lt;br /&gt;
    end&lt;br /&gt;
    Level.scatter(area.FULL_SHRINKED, &amp;quot;floor&amp;quot;, &amp;quot;blood&amp;quot;, 100)&lt;br /&gt;
    Level.player(38, 10)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''run()''' hook is very similar to that of the Hell's Arena one. In fact, other than the name change, the only real difference is that the ''column'' string has now been expanded to an array of strings, corresponding to an array of pillars. In order to randomly select pillars, '''Level.scatter_put()''' must be iterated a number of times, adding only one pillar each time: then, by adding the '''table.random_pick()''' method to the tiles-to-be-added argument, it randomly selects one of the pillars in the ''column'' array. The result is that the columns randomly have varying degrees of destructibility.&lt;br /&gt;
&lt;br /&gt;
===.OnEnter()===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function inf_arena.OnEnter()&lt;br /&gt;
    --inventory table used for build_pack()&lt;br /&gt;
    local itemPack = {&lt;br /&gt;
        {name = &amp;quot;smed&amp;quot;,  amt = 2},&lt;br /&gt;
        {name = &amp;quot;shell&amp;quot;, amt = 50},&lt;br /&gt;
    }&lt;br /&gt;
    --set up starting eq/inv&lt;br /&gt;
    build_gear(&amp;quot;shotgun&amp;quot;,&amp;quot;pistol&amp;quot;,nil,nil)&lt;br /&gt;
    build_pack(itemPack)&lt;br /&gt;
    &lt;br /&gt;
    --Print announcer messages&lt;br /&gt;
    ui.msg(&amp;quot;A devilish voice announces: \&amp;quot;Welcome to Hell's Arena, mortal! &amp;quot; ..&lt;br /&gt;
           &amp;quot;\&amp;quot;You are either very brave or very foolish. Either way I like it! &amp;quot; ..&lt;br /&gt;
           &amp;quot;\&amp;quot;And so do the crowds!\&amp;quot; Suddenly you hear screams everywhere! &amp;quot; ..&lt;br /&gt;
	   &amp;quot;\&amp;quot;Blood! Blood! BLOOD!\&amp;quot; \&amp;quot;Kill all enemies and I shall reward thee!\&amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    --spawn first wave&lt;br /&gt;
    Level.flood_monsters(Generator.being_weight()*mob_scale_factor)&lt;br /&gt;
    Level.result(1)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''OnEnter()''' makes significant use of the helper functions, using '''build_gear()''' and '''build_pack()''' to initialize the player's starting equipment and inventory. Besides the itemPack array, this only takes two lines of code, producing a much cleaner and more organized routine than in the original Hell's Arena.&lt;br /&gt;
&lt;br /&gt;
In addition, rather than directly spawning enemies using the '''Level.summon()''' method, we imitate the base game's generation code by combining '''Generator.being_weight()''', which outputs the danger level for a given map level, and '''Level.flood_monsters()''', which randomly drops enemies on the level for a given danger level. Additionally, the ''mob_scale_factor'' variable is used to change the danger level, thereby changing the scaling of the first wave.&lt;br /&gt;
&lt;br /&gt;
===.OnKill()===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function inf_arena.OnKill(being)&lt;br /&gt;
    --random message from crowdMsg array&lt;br /&gt;
    ui.msg(table.random_pick(crowdMsg))&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''OnKill()''' does exactly the same thing as the one from Hell's Arena, except that the crowd messages have been tabulated and '''table.random_pick()''' is used to choose from one of said messages. Technically, '''build_announcerMsg()''' would also work here, but since both would only require one line of code, it may as well be the simplest one to understand.&lt;br /&gt;
&lt;br /&gt;
===.OnKillAll()===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function inf_arena.OnKillAll()&lt;br /&gt;
    --print more announcer stuff&lt;br /&gt;
    if Level.result() == 1 then&lt;br /&gt;
        ui.msg(&amp;quot;The voice booms, \&amp;quot;Not bad mortal! For a weakling that you are, &amp;quot; ..&lt;br /&gt;
               &amp;quot;you show some determination.\&amp;quot; You hear screams everywhere! &amp;quot; ..&lt;br /&gt;
               &amp;quot;\&amp;quot;More Blood! More BLOOD!\&amp;quot; The voice continues, \&amp;quot;I can now &amp;quot; ..&lt;br /&gt;
               &amp;quot;let you go free, or you may try to complete the challenge!\&amp;quot;&amp;quot;)&lt;br /&gt;
    elseif Level.result() == 2 then&lt;br /&gt;
        ui.msg(&amp;quot;The voice booms, \&amp;quot;Impressive mortal! Your determination to &amp;quot; ..&lt;br /&gt;
               &amp;quot;survive makes me excited!\&amp;quot; You hear screams everywhere! &amp;quot; ..&lt;br /&gt;
               &amp;quot;\&amp;quot;More Blood! More BLOOD!\&amp;quot; \&amp;quot;I can let you go now, and give you &amp;quot; ..&lt;br /&gt;
               &amp;quot;a small reward, or you can choose to fight an additional challenge!\&amp;quot;&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
        --random message from anncrMsg.success array&lt;br /&gt;
        build_announcerMsg(anncrMsg.success)&lt;br /&gt;
    end&lt;br /&gt;
    ....&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''OnKillAll()''' has received some simplifications similar to '''OnEnter'''. To start, after the first two waves, rather than dealing with an large number of random messages here, all of it is called from the previous ''anncrMsg'' table and the '''build_announcerMsg()''' function, which randomly picks a string from an array strings, then iterates through the entire array of arrays. In the displayed run-time code, this amounts of a single line (although it is actually running quite a few lines).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
    ....&lt;br /&gt;
    local choice = ui.msg_confirm(&amp;quot;Round &amp;quot; .. Level.result() + 1 .. &amp;quot; awaits. &amp;quot; ..&lt;br /&gt;
                                  &amp;quot;Do you want to continue the fight?&amp;quot;)&lt;br /&gt;
    if choice == true then --continuing&lt;br /&gt;
        --random message from anncrMsg.choice array&lt;br /&gt;
        build_announcerMsg(anncrMsg.choice)&lt;br /&gt;
        --set up the danger level for the next wave&lt;br /&gt;
        Level.result(Level.result() + 1);&lt;br /&gt;
        Level.danger_level = Level.result();&lt;br /&gt;
        --spawn items for next wave&lt;br /&gt;
        Level.flood_items(Generator.item_amount()*item_scale_factor)&lt;br /&gt;
        --spawn enemies for next wave&lt;br /&gt;
        Level.flood_monsters(Generator.being_weight()*mob_scale_factor)&lt;br /&gt;
    ....&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Upon choosing to continue, we use '''build_announcerMsg()''' for more messages (again, only a single line of code). Then, we increment the level by one and increase the ''danger_level'' using the amount from '''Level.result()'''. (''Level.danger_level'' is actually a property of the level object.) Finally, we use the increased danger level to add items and monsters. '''Level.flood_items(Generator.item_amount())''' is the item equivalent of '''Level.flood_monsters(Generator.being_weight())'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
    else --quitting&lt;br /&gt;
        if Level.result() == 1 then&lt;br /&gt;
            ui.msg(&amp;quot;The voice booms, \&amp;quot;Coward!\&amp;quot; You hear screams everywhere! &amp;quot; ..&lt;br /&gt;
                   &amp;quot;\&amp;quot;Coward! Coward! COWARD!\&amp;quot;&amp;quot;)&lt;br /&gt;
        elseif Level.result() == 2 then&lt;br /&gt;
            ui.msg(&amp;quot;The voice booms, \&amp;quot;Too bad, you won't make it far then...!\&amp;quot; &amp;quot; ..&lt;br /&gt;
                   &amp;quot;You hear screams everywhere! \&amp;quot;Boooo...\&amp;quot;&amp;quot;)&lt;br /&gt;
        elseif Level.result() &amp;lt; 10 then&lt;br /&gt;
            ui.msg(&amp;quot;The voice booms, \&amp;quot;An impressive run, Mortal!  We appreciate &amp;quot; ..&lt;br /&gt;
                   &amp;quot;it!\&amp;quot; The crowd starts to chant! \&amp;quot;Encore! Encore!\&amp;quot;&amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
            ui.msg(&amp;quot;\&amp;quot;Ladies and gentlemen, your champion, &amp;quot;&lt;br /&gt;
                   .. Player.get_name() .. &amp;quot;. He survived &amp;quot; .. Level.result() ..&lt;br /&gt;
                   &amp;quot; rounds in our arena! That has to be some sort of record. &amp;quot; ..&lt;br /&gt;
                   &amp;quot;Give him a hand folks!\&amp;quot; The crowd starts to chant your name &amp;quot; ..&lt;br /&gt;
                   &amp;quot;and they begin throwing items into the ring!&amp;quot;)&lt;br /&gt;
            Level.flood_items(Generator.item_weight())&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Upon choosing not to continue, the announcer displays a variety of messages, although they are few enough (and specific enough) not to create another array for them. (They CAN be tabulated, but it is less bulky than for the other cases.) If the player survived at least ten waves before stopping, the crowd &amp;quot;throws items onto the stage&amp;quot; and you get some pointless gear when you're done, just as before.&lt;br /&gt;
&lt;br /&gt;
===.OnExit()===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function inf_arena.OnExit()&lt;br /&gt;
    if Level.result() &amp;lt; 10 then&lt;br /&gt;
        ui.msg(&amp;quot;The voice laughs, \&amp;quot;Flee mortal, flee! There's no hiding in hell!\&amp;quot;&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
        ui.msg(&amp;quot;The voice laughs, \&amp;quot;Remember to come back once you return to Hell &amp;quot; ..&lt;br /&gt;
               &amp;quot;for the extended stay\&amp;quot;&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    --used in .OnMortem()&lt;br /&gt;
    inf_arena.result = &amp;quot;had enough of the gauntlet at wave &amp;quot;..Level.result()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''OnExit()''' has only gained a cosmetic change in the case where the player survived more than ten waves before retreating.&lt;br /&gt;
&lt;br /&gt;
===.OnMortem()===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function inf_arena.OnMortem()&lt;br /&gt;
    local kill = player.killedby --calls kill descriptions from beings&lt;br /&gt;
    if inf_arena.result then kill = inf_arena.result end&lt;br /&gt;
        player:mortem_print( &amp;quot; &amp;quot;..player.name..&amp;quot;, level &amp;quot;..player.explevel..&amp;quot; &amp;quot;&lt;br /&gt;
                             ..&amp;quot; &amp;quot;..klasses[player.klass].name..&amp;quot;, &amp;quot;..kill )&lt;br /&gt;
        --e.g., &amp;quot;Cool Guy, level 1 Marine, had enough of the gauntlet at wave 8&amp;quot;&lt;br /&gt;
        player:mortem_print(&amp;quot; in the Infinite Arena...&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As with '''OnExit()''', '''OnMortem()''' only changes some of the text in the mortem depending on how the player ends the game.&lt;br /&gt;
&lt;br /&gt;
==Review==&lt;br /&gt;
The following is the entire source code for the Infinite Arena.&lt;br /&gt;
{{:Modding:Tutorial/The_Infinite_Arena/Source}}&lt;br /&gt;
&lt;br /&gt;
Source data: [http://dl.dropbox.com/u/54818507/inf_arena.module.zip inf_arena.module]&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Modding:Tutorial/Game_Objects</id>
		<title>Modding:Tutorial/Game Objects</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Modding:Tutorial/Game_Objects"/>
				<updated>2025-08-11T12:29:16Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Objects in DRL are based on object-oriented programming, which allows for very intracite and elegant systems of functions and variables to work in tandem. Practically everything in DRL, whether it be items and enemies, or the level itself, or even the player classes, is based in its particular object class. This section of the tutorial focuses on understanding this core part of the customization process: creating and modifying the game's objects.&lt;br /&gt;
&lt;br /&gt;
==Introducing Tables==&lt;br /&gt;
&lt;br /&gt;
A very large part of customizing the objects in DRL (weapons, powerups, enemies, etc) has to do with creating, manipulating, and referencing lua tables. All objects in the game are associated with some table or tables: they hold a number of fields, each of which contain a key (the variable) and a value. The following is an example of a very simple table:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Dude = {&lt;br /&gt;
    name = &amp;quot;John Romero&amp;quot;,&lt;br /&gt;
    type = &amp;quot;Awesome guy&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adding this to a lua script would create a table called &amp;quot;Dude&amp;quot; with two fields: the key ''name'', which is set to the value 'John Romero'; and the key ''type'', which is set to the value 'Awesome guy'. (You can use numbers for keys as well.) If we want to reference the values in this table, we can use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Dude.name    --gives the value &amp;quot;John Romero&amp;quot;&lt;br /&gt;
Dude.type    --gives the value &amp;quot;Awesome guy&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dude[&amp;quot;name&amp;quot;] --identical to Dude.name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While you can create tables yourself, more often than not you will be creating tables based on a specific class. (A class is like a variable type, except it can carry a vast amount of variables, tables, and functions within it. You just need to know how to work with them so there's no reason to go into detail.) These classes are based on the game's core objects and include &amp;quot;Beings&amp;quot;, &amp;quot;Items&amp;quot;, and &amp;quot;Missiles&amp;quot;. To create a table using a class, do not use an equal sign.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Beings{&lt;br /&gt;
    name = &amp;quot;super enemy&amp;quot;,&lt;br /&gt;
    ascii = &amp;quot;S&amp;quot;&lt;br /&gt;
    ....&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is that a new table called &amp;quot;super enemy&amp;quot; will exist as a part of the Beings class.&lt;br /&gt;
&lt;br /&gt;
There are four important parts to understand when working with classes in DRL modding:&lt;br /&gt;
&lt;br /&gt;
*The &amp;lt;u&amp;gt;prototype&amp;lt;/u&amp;gt; is the game object's mold: the game uses it to make as many objects as necessary. Whenever you create a new object, you will do so by creating the prototype.&lt;br /&gt;
*The &amp;lt;u&amp;gt;properties&amp;lt;/u&amp;gt; are the variables in a particular object that can be modified for said object. They are distinct from prototype: changing values in the prototype affects ALL objects, while changing properties affects only the object in your scope.&lt;br /&gt;
*The &amp;lt;u&amp;gt;engine hooks&amp;lt;/u&amp;gt; are ways to execute code when particular events occur for an object. Hooks are why phase devices teleport you around when you use them (with an OnUse hook) and why shamblers regenerate their health every turn (with an OnAct hook).&lt;br /&gt;
*The &amp;lt;u&amp;gt;API&amp;lt;/u&amp;gt; is a set of functions that lets you interact with various pieces of the DRL engine. Often this gives you an easier way to change the prototype after initializing it, although there are a wide-ranging collection of functions for each class that allow for interesting game possibilities.&lt;br /&gt;
&lt;br /&gt;
We will cover all of these in the following sections.&lt;br /&gt;
&lt;br /&gt;
==Prototypes==&lt;br /&gt;
Every game object starts with its prototype. It is meant to be a stable definition of an object from which various properties of an instantiated object can be used and modified. We will begin by looking at the basic keys used to designate an Item object prototype (full documentation can be found [[Modding:Item|here]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Items{&lt;br /&gt;
    name = &amp;quot;a thing&amp;quot;,      --name of the item, as viewed in-game&lt;br /&gt;
    id = &amp;quot;thing&amp;quot;,          --item's in-script reference name (defaults to name)&lt;br /&gt;
    color = LIGHTGRAY,     --color of item, as viewed in-game&lt;br /&gt;
    level = 1,             --minimum in-game floor on which that item can appear&lt;br /&gt;
    weight = 1000,         --weighted likelihood of item spawning&lt;br /&gt;
    type = ITEMTYPE_NONE,  --type of item&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should notice that, in addition to the normal value types, there are special values used for ''color'' and ''type''. Very often there are a number of pre-defined values by the game and can be found in full in the [[Modding:Constants|constants and flags]] page, which should be used in some of the prototype fields. In particular, ''color'' can be [[Modding:Constants#Colors|any of sixteen colors]] (e.g., LIGHTGRAY) and ''type'' can be any of [[Modding:Constants#ItemType|twelve particular item settings]]. Most often you will see types such as ITEMTYPE_RANGED, ITEMTYPE_PACK, and ITEMTYPE_POWER used, but you should take a look at all of them to see what best suits your need for the particular item.&lt;br /&gt;
&lt;br /&gt;
ITEMTYPE_RANGED, for instance, contains the following additional prototype keys:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Items{&lt;br /&gt;
    name 'big gun',&lt;br /&gt;
    ....&lt;br /&gt;
    type = ITEMTYPE_RANGED,&lt;br /&gt;
    desc = &amp;quot;It's a really big gun.&amp;quot;, --in-game description, as viewed in the inventory&lt;br /&gt;
    ascii = &amp;quot;}&amp;quot;,                     --single character representing the weapon, as viewed in-game&lt;br /&gt;
    damage = &amp;quot;4d4&amp;quot;,                  --weapon's damage: should be written as 'XdY' ala dice notation&lt;br /&gt;
    damagetype = DAMAGE_BULLET,      --weapon's damage type&lt;br /&gt;
    group = &amp;quot;weapon-biggun&amp;quot;,         --weapon's category: mainly for score-keeping&lt;br /&gt;
    ammoID = &amp;quot;bigbullet&amp;quot;             --ammo that weapon uses: use the id of that ammo here&lt;br /&gt;
    fire = 10,                       --how quickly the weapon fires, in turns (1 second = 10 turns)&lt;br /&gt;
    acc = 3,                         --how accurate the weapon is&lt;br /&gt;
    ammomax = 50,                    --weapon's clip size&lt;br /&gt;
    radius = 0,                      --size of shot's explosion radius&lt;br /&gt;
    shot = 5,                        --how many shots the weapon fires&lt;br /&gt;
    shotcost = 1,                    --how much ammo each shot takes&lt;br /&gt;
    missile = &amp;quot;big_shot&amp;quot;,              --what the projectile of the weapon is&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the ''desc'' key, since the string itself contains a single quote, we can wrap the string around double-quotes: lua handles this without error. Alternatively, we could use a backslash (such as \') to add otherwise-unusable characters in strings.&lt;br /&gt;
&lt;br /&gt;
There are also some additional keys for alt-fires and alt-reloads, but these are the most important for setting up a ranged weapon. Notice that the last key requires an identifier from a missile object: while there are a number of pre-set missiles from which you can choose, you can also [[Modding:Missile|create your own missile prototype]] and use the id key from that prototype for the missile (the above example would require a missile object with the id of 'big_shot').  Additionally, if the missile you design is unique to this weapon, you can define the prototype directly in the weapon, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Items{&lt;br /&gt;
    name 'big gun',&lt;br /&gt;
    ....&lt;br /&gt;
    missile = Missiles{ --assign missile prototype&lt;br /&gt;
        ....            --missile prototype keys go here&lt;br /&gt;
    }                   --missile prototype completes on this line&lt;br /&gt;
}                       --item prototype completes on this line&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In creating the missile this way, you can omit the identifier of the missile, as it is automatically created for you (and should not need to be called anyway).&lt;br /&gt;
&lt;br /&gt;
Referencing and changing prototype values is a more difficult than changing properties (see below), and potentially dangerous depending on what you are trying to do. It is quite possible, however, by first referencing the class that the prototype belongs to, followed by the id of the prototype, followed by the key whose value you wish to reference/change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local new_damage = &amp;quot;3d3&amp;quot;         --create a damage variable&lt;br /&gt;
items.pistol.damage = new_damage --change the damage key of the pistol prototype&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Executing this code will change the damage of every pistol object in the game. In general, this is not recommended for use with any code that occurs after the game has already started.&lt;br /&gt;
&lt;br /&gt;
==Properties==&lt;br /&gt;
An object's properties are its own unique set of characteristics that set it apart from any other object in the game, including other copies of the same object. An object will initially receieve its property values from the object's prototype on creation, but they can be changed constantly after this without affecting other object instances.&lt;br /&gt;
&lt;br /&gt;
One easy object that can have its properties manipulated without worrying about other instances is the player. As there is only ever one player in the game at any time, it is much easier to simply manipulate property values rather than digging into the prototype. The player has properties from both the [[Modding:Player|player object]] and the [[Modding:Being|being object]], since the player is actually a sub-class of beings. If we wanted to change the player's health and experience level, we would do it in the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
player.hp = player.hp + 10 --increases player's HP by 10&lt;br /&gt;
player.explevel = 5        --sets player's level to 5&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the health property is ''hp'', not ''HP'': while this is just a case-sensitive example, sometimes the key of a property field representing a prototype key can be very different (beings have the ''XP'' field for how much experience they give, but an ''expvalue'' for their corresponding property). Be aware of these differences when coding.&lt;br /&gt;
&lt;br /&gt;
Properties must always refer to a specific instance of an object. While it may seem bothersome to have to point to a specific object every time you want to change a property, these are automatically handled by engine hooks and the API, as we will see shortly.&lt;br /&gt;
&lt;br /&gt;
==Engine Hooks==&lt;br /&gt;
Engine hooks are functions that allow you to truly customize object interaction. They are associated with specific events in the DRL engine and essentially allow for input of anything you want to occur during those events.&lt;br /&gt;
&lt;br /&gt;
Like prototype keys, engine hooks are added during the initialization process of the object. They should be placed at the end of all the prototype keys, and are written much like functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Beings{&lt;br /&gt;
    name = &amp;quot;nasty&amp;quot;,&lt;br /&gt;
    ....                            --other prototype keys are added&lt;br /&gt;
    OnAction = function(being)        --engine hook is called&lt;br /&gt;
        ....                        --code to be executed in the hook goes here&lt;br /&gt;
    end,                            --function ends&lt;br /&gt;
}                                   --prototype ends&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following shows a being called &amp;quot;nasty&amp;quot; getting initialized into DRL and, with it, the hook '''OnAction()'''. Hooks work just like functions do, carrying input arguments and a potential output return value. '''OnAction()''' has a ''being'' input argument, which is used as a reference to the being whenever '''OnAction()''' triggers for that particular being; '''OnAction()''' has a void output argument, meaning that you cannot return a value using this hook. (Note that, for hooks with output arguments, the return value affects an outcome on the engine side rather than a usable value in the code.) The '''OnAction()''' hook itself is triggered whenever a being carries out an action (usually once per second), and so will be constantly called over the course of the being's lifetime.&lt;br /&gt;
&lt;br /&gt;
Hooks are applied to a particular instance of an object, not the prototype itself. This means that, if you're changing, for instance, the HP value of a being, you must call the being's ''hp'' property rather than its prototype key. What makes the input argument so useful is that it automatically refers to whatever being activated the hook, rather than you needing to specify exactly which being needs to call the function. Thus, if we want a being object that regenerates its health on every action (like the shambler), we would write the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Beings{&lt;br /&gt;
    name = &amp;quot;regenerator&amp;quot;,&lt;br /&gt;
    ....&lt;br /&gt;
    OnAction = function(being)       --initialize the hook&lt;br /&gt;
        if being.hp &amp;lt; being.hpmax     --prevent being from healing past maximum health&lt;br /&gt;
            being.hp = being.hp + 1   --being gains one HP&lt;br /&gt;
        end                         --end of conditional statement&lt;br /&gt;
    end,                            --end of engine hook&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First, we check to see if the being instance's health is less than its maximum health: if this is true, we raise the hp property of the instance by one; if not, nothing happens. Once the if statement finishes, there is nothing left for the function to do, and so it ends as well. '''OnAction()''' will make it so that the if statement is called every time the being instance acts, so it could be hard to kill something like this! (Anyone trying to kill shambler with a shotgun should understand well enough.)&lt;br /&gt;
&lt;br /&gt;
Most of the engine hooks are found with the item and level object classes, since there are a number of events that the engine specifically checks for these objects over the course of their lifetimes. Common hooks are '''OnCreate()''', '''OnEnter()''', and '''OnDestroy()'''/'''OnDie()''' (which practically do the same thing, just for different object classes).&lt;br /&gt;
&lt;br /&gt;
==API==&lt;br /&gt;
Object API is very simple in DRL: for each object class, there is a set of pre-defined functions, called methods, that allow modders to manipulate objects of that class. Most, if not all, of the methods in an object's API are otherwise impossible to create within lua itself, which is why we are lucky to have them available. Unlike functions, however, you need not define methods as such: simply writing the functional expression itself (without preceding it with &amp;quot;local function&amp;quot;, for example) is all that is necessary.&lt;br /&gt;
&lt;br /&gt;
In lua, the convention for methods is to use a period between the class name and the method name. If the first argument requires a particular instance of an object in that class, one can use shorthand by writing out the object instance, followed by a colon, then the method name, at which point the first argument is automatically used in the method without having to explicitly write it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
being.new(id)             --this will allocate a new instance of the being object id to memory&lt;br /&gt;
being.destroy(some_being) --this will deallocate a being instance called some_being from memory&lt;br /&gt;
&lt;br /&gt;
some_being:destroy()      --identical to being.destroy(some_being)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whenever you are not working with a particular instance of an object, it usually means you are creating a new one. For [[Modding:Coord|some objects]], this is a very important use. However, most of the API is meant to interact with specific object instances, so we will take a look at an example for such a method.&lt;br /&gt;
&lt;br /&gt;
Let us suppose we want to make an enemy explode whenever it dies. One way to do this is the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Beings{&lt;br /&gt;
    name = &amp;quot;exploder&amp;quot;&lt;br /&gt;
    ....&lt;br /&gt;
    OnDie = function(self)                                             --engine hook upon death&lt;br /&gt;
       position = self:get_position()                                  --position for being is found&lt;br /&gt;
       Level.explosion(position, 3, 30, 5, 5, YELLOW, &amp;quot;&amp;quot;, DAMAGE_FIRE) --explosion occurs on the map&lt;br /&gt;
    end,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we use the '''OnDie()''' hook to execute code whenever an &amp;quot;exploder&amp;quot; being dies. Creating an explosion on the map is done with the method '''Level.explosion()''', which carries quite a few input arguments: coordinates on the map where explosion should happen, radius of explosion, millisecond delay on explosion's path, damage dice, side of damage dice, color of explosion, sound id for explosion, and damage type of explosion. (Note that there are even more arguments, but these can be safely ignored if they appear after all the arguments we end up using.) The coordinates of the being instance are not immediately accessible in its properties, but can be found with the '''thing:get_position()''' method (where the Thing in this case is the being instance, or ''self'', defined inside of the OnDie hook). In order to get the coordinates, we assign an output argument ''position'' to '''thing:get_position''', and use it in '''Level.explosion''' when we need to define them.&lt;br /&gt;
&lt;br /&gt;
==Review==&lt;br /&gt;
As a final, rather large example, we will take a look at one of the enemies from the HereticRL mod (though this exact code might be outdated at some point), the undead warrior. The undead warrior is a fairly straight-forward enemy with the unique twist in that it will occasionally throw red axes (as opposed to green ones), which deal much more damage. To start, we will first need to initialize the two axe weapons: since the undead warrior will have more than one weapon, we cannot inline them within the being definition.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Items{&lt;br /&gt;
	name = &amp;quot;nat_undeadgreen&amp;quot;,       --this is the green axe weapon&lt;br /&gt;
	id = &amp;quot;nat_undeadgreen&amp;quot;,&lt;br /&gt;
	type = ITEMTYPE_NRANGED,        --natural ranged-weapon type&lt;br /&gt;
	damage = &amp;quot;2d6&amp;quot;,&lt;br /&gt;
	damagetype = DAMAGE_BULLET,&lt;br /&gt;
	fire = 10,&lt;br /&gt;
	missile = {                     --in-line missile definition&lt;br /&gt;
		soundID = &amp;quot;undead&amp;quot;,&lt;br /&gt;
		ascii = &amp;quot;x&amp;quot;,&lt;br /&gt;
		color = LIGHTGREEN,&lt;br /&gt;
		delay = 80,&lt;br /&gt;
		miss_base = 10,&lt;br /&gt;
		miss_dist = 5,&lt;br /&gt;
	},&lt;br /&gt;
	weight = 0,                     --don't want these being generated!&lt;br /&gt;
	flags = {IF_NODROP, IF_NOAMMO}, --these are standard flags for NRANGED items&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Items{&lt;br /&gt;
	name = &amp;quot;nat_undeadred&amp;quot;,         --this is the red axe weapon&lt;br /&gt;
	id = &amp;quot;nat_undeadred&amp;quot;,&lt;br /&gt;
	type = ITEMTYPE_NRANGED,&lt;br /&gt;
	damage = &amp;quot;6d2&amp;quot;,                 --better damage than green axe (on average)&lt;br /&gt;
	damagetype = DAMAGE_PLASMA,     --stronger damage type&lt;br /&gt;
	fire = 10,&lt;br /&gt;
	missile = {                     --in-line missile definition&lt;br /&gt;
		soundID = &amp;quot;undead&amp;quot;,&lt;br /&gt;
		ascii = &amp;quot;x&amp;quot;,&lt;br /&gt;
		color = LIGHTRED,       --different color&lt;br /&gt;
		delay = 50,&lt;br /&gt;
		miss_base = 10,&lt;br /&gt;
		miss_dist = 3,          --misses less&lt;br /&gt;
	},&lt;br /&gt;
	weight = 0,&lt;br /&gt;
	flags = {IF_NODROP, IF_NOAMMO},&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These must be placed in the code before we define the undead warrior itself, as they are called within the being prototype.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Beings{&lt;br /&gt;
	name = &amp;quot;undead warrior&amp;quot;,&lt;br /&gt;
	name_plural = &amp;quot;undead warriors&amp;quot;,     --this would work as such by default&lt;br /&gt;
	id = &amp;quot;undead&amp;quot;,                       --small ids are nice for calls&lt;br /&gt;
	ascii = &amp;quot;u&amp;quot;,&lt;br /&gt;
	color = LIGHTGRAY,&lt;br /&gt;
	sprite = 0,                          --necessary, always set to 0 for now&lt;br /&gt;
	corpse = true,                       --whether being leaves a corpse&lt;br /&gt;
	toDam = 6,                           --inherent damage modifier (for melee)&lt;br /&gt;
	toHit = 4,                           --inherent accuracy modifier&lt;br /&gt;
	speed = 100,                         --time of actions: 100 = 1s; &amp;lt;100 = &amp;gt;1s; &amp;gt;100 = &amp;lt;1s&lt;br /&gt;
	armor = 2,                           --protection value&lt;br /&gt;
	danger = 6,                          --weight for generation, can also determine experience&lt;br /&gt;
	XP = 0,                              --set experience specially&lt;br /&gt;
	weight = 250,&lt;br /&gt;
	minLev = 7,                          --lowest floor being will generate&lt;br /&gt;
	maxLev = 20,                         --highest floor being will generate&lt;br /&gt;
	HP = 50,&lt;br /&gt;
	attackchance = 60,                   --chance being will attack as its action&lt;br /&gt;
	toHitMelee = 0,                      --inherent accuracy modifier (for melee, adds to toHit)&lt;br /&gt;
	res_fire = 50,                       --percentage resistance to damage type DAMAGE_FIRE&lt;br /&gt;
	res_acid = 50,&lt;br /&gt;
	ai_type = &amp;quot;natural_melee_ranged_ai&amp;quot;, --how the enemy moves/reacts, can define yourself&lt;br /&gt;
	desc = &amp;quot;As part of the Order's insidious plot to control your world, they've recruited the dead, &amp;quot; ..&lt;br /&gt;
               &amp;quot;gave them armor and armed them with deadly magic axes. Now they guard the evil cities and &amp;quot; ..&lt;br /&gt;
               &amp;quot;toss their infinite supply of axes at any elf who passes by.&amp;quot;,&lt;br /&gt;
	kill_desc = &amp;quot;took an axe to the face from an undead warrior&amp;quot;, --shows up in mortem if you died to this being&lt;br /&gt;
	kill_desc_melee = &amp;quot;chopped in two by an undead warrior&amp;quot;,      --same as above but by melee attack&lt;br /&gt;
	OnCreate = function(self)&lt;br /&gt;
		self.eq.weapon = item.new(&amp;quot;nat_undeadgreen&amp;quot;)&lt;br /&gt;
	end,&lt;br /&gt;
	OnAction = function(self)&lt;br /&gt;
		if(math.random(6) == 1) then&lt;br /&gt;
			self.eq.weapon = item.new(&amp;quot;nat_undeadred&amp;quot;)&lt;br /&gt;
		else&lt;br /&gt;
			self.eq.weapon = item.new(&amp;quot;nat_undeadgreen&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
    end,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Typically, for an enemy that has a ranged attack, you would use the prototype field ''weapon'' and in-line an item definition with type ITEMTYPE_NRANGED. However, since the undead warrior has two different attacks, we choose to assign it two separate weapons over the course of its lifetime through engine hooks.&lt;br /&gt;
&lt;br /&gt;
*Whenever an undead warrior is created, it is given a green axe in its weapon equipment slot: this is done by assigning a new item to the weapon field of the equipment property with an '''OnCreate()''' hook.&lt;br /&gt;
*On every action there's a chance for the undead warrior to get a red axe in its weapon equipment slot.&lt;br /&gt;
**First we call the '''OnAction()''' hook to make a check on every action.&lt;br /&gt;
**Next, we supply a random condition using '''math.random(''num'')''' (which randomly chooses an integer between 1 and ''num''). if('''math.random(6)''' == 1) produces a 1/6 chance of the condition being true.&lt;br /&gt;
**If the condition becomes true, we create a new item (this time a red axe) to the same field as before.&lt;br /&gt;
**If the condition is false, we put a new green axe there instead. This is to ensure that the red axe is only in the undead warrior's equipment slot 1/6 of the time.&lt;br /&gt;
&lt;br /&gt;
And that's all there is to it! You'll want to change the ''soundID'' in the missile definitions, but otherwise this code should run in any module you create.&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Modding:Tutorial/Custom_Beings</id>
		<title>Modding:Tutorial/Custom Beings</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Modding:Tutorial/Custom_Beings"/>
				<updated>2025-08-11T12:28:44Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In the following tutorial you will learn the basics of [[Modding:Being|being objects]]. Beings are anything in the game that can act independently on the map, without the need to specifically interact with with it. The [[Modding:Player|player object]] is also a being, and so all of the topics mentioned here will also apply to the player (with some exceptions). We will learn how to create new beings, as well as how to apply various modifications in order to produce special and unique varieties.&lt;br /&gt;
&lt;br /&gt;
==Prototype==&lt;br /&gt;
The following is a complete list of the being prototype table:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Beings{&lt;br /&gt;
    name            = &amp;quot;evil marine&amp;quot;,                --required field&lt;br /&gt;
    name_plural     = &amp;quot;evil marines&amp;quot;,               --defaults to name with an appended 's'&lt;br /&gt;
    id              = &amp;quot;badclone&amp;quot;,                   --defaults to lowercased first word of 'name'&lt;br /&gt;
    ascii           = &amp;quot;@&amp;quot;,                          --required field&lt;br /&gt;
    color           = DARKGRAY,                     --required field&lt;br /&gt;
    sound_id        = &amp;quot;soldier&amp;quot;,                    --checked if 'id' has no sound bindings&lt;br /&gt;
    desc            = &amp;quot;It's you, but evil.&amp;quot;         --required field&lt;br /&gt;
    kill_desc       = &amp;quot;fragged by your evil clone&amp;quot;, --defaults to &amp;quot;&amp;quot;&lt;br /&gt;
    kill_desc_melee = &amp;quot;mauled by your evil clone&amp;quot;,  --defaults to &amp;quot;&amp;quot;&lt;br /&gt;
    weight          = 1,                            --required field&lt;br /&gt;
    danger          = 12,                           --required field&lt;br /&gt;
    minLev          = 20,                           --required field&lt;br /&gt;
    maxLev          = 100,                          --defaults to 200&lt;br /&gt;
    corpse          = true,                         --defaults to true&lt;br /&gt;
    HP              = 100,                          --defaults to 10&lt;br /&gt;
    armor           = 2,                            --defaults to 0&lt;br /&gt;
    res_bullet      = 0,                            --defaults to 0&lt;br /&gt;
    res_melee       = 0,                            --defaults to 0&lt;br /&gt;
    res_shrapnel    = 0,                            --defaults to 0&lt;br /&gt;
    res_acid        = 0,                            --defaults to 0&lt;br /&gt;
    res_fire        = 0,                            --defaults to 0&lt;br /&gt;
    res_plasma      = 0,                            --defaults to 0&lt;br /&gt;
    weapon          = &amp;quot;bazooka&amp;quot;,                    --defaults to &amp;quot;&amp;quot; (no weapon)&lt;br /&gt;
    toDam           = 5,                            --defaults to 0&lt;br /&gt;
    toHit           = 5,                            --defaults to 0&lt;br /&gt;
    toHitMelee      = 0,                            --defaults to 0&lt;br /&gt;
    attackchance    = 60,                           --defaults to 75&lt;br /&gt;
    vision          = 11,                           --defaults to 9&lt;br /&gt;
    speed           = 100,                          --defaults to 100&lt;br /&gt;
    XP              = 2000,                         --defaults to 3*'danger'^2+20&lt;br /&gt;
    ai_type         = &amp;quot;cyberdemon_ai&amp;quot;,              --defaults to &amp;quot;&amp;quot;&lt;br /&gt;
    group           = 0,                            --defaults to 0&lt;br /&gt;
    flags           = {},                           --defaults to {}&lt;br /&gt;
    bulk            = 100,                          --defaults to 100&lt;br /&gt;
    sprite          = 0,                            --required field, set to 0&lt;br /&gt;
    overlay         = {0,0,0,0},                    --defaults to {0,0,0,0}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*''name'' is what the being appears to be in-game (e.g., using the 'look' command).&lt;br /&gt;
*''name_plural'' is what the game uses when a pluralized form of the name is required (e.g., in the kills section of the mortem).&lt;br /&gt;
*''id'' is the being identifier, to be used in lua whenever you want to call the item prototype.&lt;br /&gt;
*''ascii'' is the ASCII character used to represent the being in the console.&lt;br /&gt;
*''color'' is one of 16 (4-bit) [[Modding:Constants#Colors|colors]] that you can use to distinguish the being on the map.&lt;br /&gt;
*''sound_id'' is what you want the being's sound bindings to map to. If the being's id is not registered for sound bindings, it will use this key instead (useful when mapping several beings to a single set of sounds). (Note that in the current version, registering sound bindings for custom beings requires direct manipulation of the prototype. This will be explained later on.)&lt;br /&gt;
*''desc'' is the description of the enemy, as seen when using the 'more' command while looking.&lt;br /&gt;
*''kill_desc'' is what shows at the top of a mortem if the player was killed by this being's ranged attack.&lt;br /&gt;
*''kill_desc_melee'' is what shows at the top of a mortem if the player was killed by this being's melee attack.&lt;br /&gt;
*''weight'' affects the frequency that the being will appear, for random monster generation purposes. &lt;br /&gt;
*''danger'' is the capacity by which the being can be added to the map, for random monster generation purposes.&lt;br /&gt;
*''minLev'' is the earliest floor on which the being can appear, for random monster generation purposes.&lt;br /&gt;
*''maxLev'' is the latest floor on which the being can appear, for random monster generation purposes. ''weight'', ''danger'', ''minLev'', and ''maxLev'' are only important on levels that randomly generate beings using Level.flood_monsters(). &lt;br /&gt;
*''corpse'' determines if the being will generate a corpse upon death. Alternatively, you can choose a cell (by referencing its id here) that the being will leave upon death.&lt;br /&gt;
*''HP'' determines how much damage the being can take before it dies.&lt;br /&gt;
*''armor'' determines how much damage the being absorbs before HP is subtracted, modified by the damage type of the source. Note that, without BF_HARDY, armor can only reduce damage to 1.&lt;br /&gt;
*''res_[damage_type]'' sets the internal [[resistances|resistance]] of the being for damage_type. Internal resistance affects both torso and foot sources. Note that amount of damage absorbed by resistance is calculated before any damage absorption due to ''armor'', and that 100% resistance can reduce damage to 0 (though anything less will not).&lt;br /&gt;
*''weapon'' sets the being's default weapon (in its weapon equipment slot). This can either be an id for a separate [[Modding:Item|item prototype]], or it can be inlined into the being prototype. If inlined, the following is true by default for the item prototype:&lt;br /&gt;
**''type'' is set to ITEMTYPE_NRANGED&lt;br /&gt;
**''id'' is automatically assigned (although no lua-based id (sid) will exist)&lt;br /&gt;
**''weight'' and ''sprite'' are set to 0&lt;br /&gt;
**IF_NODROP and IF_NOAMMO are added to the ''flags'' table&lt;br /&gt;
*''toDam'' is the damage modifier to the being's natural melee attack. It deals 1d3 damage unmodified.&lt;br /&gt;
*''toHit'' is the [[accuracy]] modifier to all of the being's attacks.&lt;br /&gt;
*''toHitMelee'' is the accuracy modifier to the being's melee attack. toHit and toHitMelee can have negative values (e.g., in order to set melee to-hit to 0 while keeping ranged to-hit at some positive value).&lt;br /&gt;
*''attackchance'' is the chance that the being will attack on a given turn. This can be overridden with custom AI.&lt;br /&gt;
*''vision'' is the [[distance]] in which the being can see, assuming no cells that block vision are present.&lt;br /&gt;
*''speed'' is the speed of any of the being's internal actions (e.g., movement and attacking). Values greater than 100 result in a faster being, while values less than 100 result in a slower being. The maximum value this can be set to is 255.&lt;br /&gt;
*''XP'' determines how much experience the player receives upon killing the enemy. Only the player can benefit from experience.&lt;br /&gt;
*''ai_type'' sets the AI of the being. There are a number of pre-defined AI for the base monsters, but it is possible to define your own.&lt;br /&gt;
*''group'' assigns the being to a particular group of other beings that it will not attack. Beings of different groups, by default, will attack each other. In the base game, all monsters are in group 0, while the player is in group 1.&lt;br /&gt;
*''flags'' defines what [[Modding:Constants#Being Flags|being flags]] you give the being.&lt;br /&gt;
*''bulk'' is an unused parameter, so you can ignore it entirely.&lt;br /&gt;
*''sprite'' is what will eventually be the graphical tile of the being. Set to 0 and ignore it for now.&lt;br /&gt;
*''overlay'', like sprite, is based on there being graphical tiles in DRL. You can ignore this key entirely for the time being.&lt;br /&gt;
&lt;br /&gt;
==Properties==&lt;br /&gt;
Several of the being object properties are identical to their prototype counterparts, others differ only by name. The comparisons are given here:&lt;br /&gt;
&lt;br /&gt;
*The following properties are the same as the prototype keys:&lt;br /&gt;
**''attackchance''&lt;br /&gt;
**''vision''&lt;br /&gt;
**''speed''&lt;br /&gt;
**''armor''&lt;br /&gt;
*The following properties have a different name than a prototype key, but function exactly the same as the key:&lt;br /&gt;
**The key ''sound_id'' is broken up into the following properties:&lt;br /&gt;
***''soundact'' is heard occasionally whenever the being acts&lt;br /&gt;
***''soundhit'' is heard whenever the being takes damage&lt;br /&gt;
***''sounddie'' is heard whenever the being dies&lt;br /&gt;
***''soundattack'' is heard whenever the being uses a ranged attack&lt;br /&gt;
***''soundmelee'' is heard whenever the being uses a melee attack&lt;br /&gt;
***''soundhoof'' is heard whenever the being moves (often disabled on most beings)&lt;br /&gt;
**''hpmax'' is the property of ''HP''&lt;br /&gt;
**''tohit'' is the property of ''toHit''&lt;br /&gt;
**''todam'' is the property of ''toDam''&lt;br /&gt;
**''tohitmelee'' is the property of ''toHitMelee''&lt;br /&gt;
**''expvalue'' is the property of ''XP''&lt;br /&gt;
*There are also a number of properties that are instantiated by default without automatic customization. They are as follows:&lt;br /&gt;
**''proto'' is the being's prototype. Don't change this unless you're planning on doing something really hacky.&lt;br /&gt;
**''hp'' is the being's current health. It defaults to the ''HP'' prototype key, but changes whenever the being takes damage.&lt;br /&gt;
**''scount'' is the being's speed count, or [[Time#Fractional_Time|energy]]. For each turn that passes, all beings' ''scount'' is increased 100 (modified by each's ''speed''); whenever a particular being takes an action, its ''scount'' is decreased by the amount of game seconds it takes for the action, multiplied by 1000. (For custom actions, ''scount'' must be modified manually in order for the action to take any time.)&lt;br /&gt;
**''todamall'' is a damage modifer applied to all of the being's attack (melee and ranged). (When the player invests in [[Son of a Bitch]], this property is modified.)&lt;br /&gt;
**Three properties affect the time in which particular actions are taken, given as a percentage relative to ''speed'':&lt;br /&gt;
***''movetime'' affects how much time it takes for the being to move: for the player, this also corresponds to an increased dodge chance. (When the player invests in [[Hellrunner]], this property is modified.)&lt;br /&gt;
***''reloadtime'' affects how much time it takes for the being to reload its weapon. (When the player invests in [[Reloader]], this property is modified.&lt;br /&gt;
***''firetime'' affect how much time it takes for the being to attack. (When the player invests in [[Finesse]], this property is modified.)&lt;br /&gt;
**''bodybonus'' reduces knockback by the number given, and any value greater than 0 will prevent health decay above 100%. (When the player invests in [[Badass]], this property is modified.)&lt;br /&gt;
**''pistolbonus'' lowers firetime and increases damage whenever the being is using a weapon with the item flag IF_PISTOL. (When the player invests in [[Son of a Gun]], this property is modified.)&lt;br /&gt;
**''rapidbonus'' modifies the number of shots fired from a weapon whose &amp;quot;shots&amp;quot; property is greater than one. (When the player invests in [[Triggerhappy]], this property is modified.)&lt;br /&gt;
**''techbonus'' increases the number of mods that can be added to the being's equipment, as well as what tier of assemblies the being can create. (When the player invests in [[Whizkid]], this property is modified.)&lt;br /&gt;
*Finally, there are the properties that beings inherit from [[Modding:Thing|things]]. (Some of the thing properties are readonly, meaning they can't be changed once the instantiated object is initialized. These will be bolded for clarification.)&lt;br /&gt;
**The following properties are the same as the prototype keys:&lt;br /&gt;
***''color''&lt;br /&gt;
***'''''id'''''&lt;br /&gt;
***''name''&lt;br /&gt;
***''sprite''&lt;br /&gt;
***''res_bullet''&lt;br /&gt;
***''res_shrapnel''&lt;br /&gt;
***''res_melee''&lt;br /&gt;
***''res_acid''&lt;br /&gt;
***''res_fire''&lt;br /&gt;
***''res_plasma''&lt;br /&gt;
**The following properties have a different name than a prototype key, but function exactly the same as the key:&lt;br /&gt;
***''picture'' is the property of ''ascii''&lt;br /&gt;
***''nameplural'' is the property of ''name_plural''&lt;br /&gt;
**The following properties are automatically given by default:&lt;br /&gt;
***'''''sid''''' is a string identifier, similar to '''''id'''''. This is what is used dominantly by modders, and is set based on the being's ''id'' key. &lt;br /&gt;
***'''''uid''''' is a unique identifier across all instantiated objects. This is often used to save the state of a game.&lt;br /&gt;
***'''''x''''' is the x-coordinate of the being on the map.&lt;br /&gt;
***'''''y''''' is the y-coordinate of the being on the map. '''''x''''' and '''''y''''' make up a being's [[Modding:Coord|coordinate]] indirectly.&lt;br /&gt;
***'''''__ptr''''' is a pointer to the object in the engine: you'll never have to worry about this property.&lt;br /&gt;
&lt;br /&gt;
==Engine Hooks==&lt;br /&gt;
Beings come with three hooks:&lt;br /&gt;
&lt;br /&gt;
*'''OnCreate'''(''being'') is called when ''being'' is allocated to memory (i.e., created but not necessarily placed on the map). Use this function to add or modify properties, or potentially cause special cases to occur depending on the circumstances of the creation.&lt;br /&gt;
*'''OnAction'''(''being'') is called whenever ''being'' takes an action. This is where a great deal of code used to be added when a modder wanted to manipulate the being's special abilities and/or AI, but is now mostly used as a means to have abilities that should be activated on every action. For more complicated setups, the modder should create a special AI for the being (explained in a separate tutorial).&lt;br /&gt;
*'''OnDie'''(''being'',''overkill'') is called whenever ''being'' dies. The ''overkill'' parameter is a boolean that only triggers '''OnDie()''' if ''being'' was gibbed on death. (In this way you can set up two separate '''OnDie()''' hooks to the same being prototype.)&lt;br /&gt;
&lt;br /&gt;
==Basic Examples==&lt;br /&gt;
There are quite a few things you can do with beings. The following examples will go through the more common uses for beings: you should feel free to work with any of these as a base for your own designs.&lt;br /&gt;
&lt;br /&gt;
===Dummy===&lt;br /&gt;
Dummies are beings that cannot be killed but cannot kill, either. They are mainly used as targets, potentially as a trigger or simply something to shoot at. In spite of this simple purpose, there is a lot you can do with dummies. First, let's add the prototype fields:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Beings{&lt;br /&gt;
    name   = &amp;quot;dummy&amp;quot;,&lt;br /&gt;
    id     = &amp;quot;dummy&amp;quot;,&lt;br /&gt;
    ascii  = &amp;quot;I&amp;quot;,&lt;br /&gt;
    color  = WHITE,&lt;br /&gt;
    desc   = &amp;quot;Nothing but a punching bag.&amp;quot;&lt;br /&gt;
    sprite = 0,&lt;br /&gt;
    weight = 0,&lt;br /&gt;
    danger = 0,&lt;br /&gt;
    minLev = 0,&lt;br /&gt;
    speed  = 0,&lt;br /&gt;
    flags  = {BF_INV},&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since the dummy isn't going to be attacking at all, we can ignore a great deal of keys, and unless we want the dummy to be able to randomly spawn with other enemies, we set the generation parameters to 0. The important factors to this prototype involve the being's ''speed'' and ''flags'':&lt;br /&gt;
&lt;br /&gt;
*''speed'' is set to 0, so the dummy will never have any turn whatsoever.&lt;br /&gt;
**If you want the dummy to attack but not move, you can set the BF_SESSILE flag (which does exactly that).&lt;br /&gt;
**If, instead, you want the dummy to move but not attack, you can set the BF_NOMELEE flag (which prevents melee attacks). To avoid ranged attacks, just don't give the dummy a ranged weapon with which to attack.&lt;br /&gt;
*&amp;quot;BF_INV&amp;quot; is the flag set when a player is [[effects#invulnerable|invulnerable]], which prevents any damage from being taken regardless of its source (even going so far as to include a nuclear explosion!).&lt;br /&gt;
**If you want to prevent only certain types of damage, you can alternatively set any of the six resistance keys to 100, allowing for complete immunity against that type of damage. Note that there is no resistsance for piercing attacks, nor would this dummy ever withstand a nuclear explosion.&lt;br /&gt;
**If you want the dummy to be able to take damage but not die, you can set the HP to a ridiculous amount, such as 1000, and use a hook to set its ''hp'' to ''hpmax''. This should prevent death in all but the most extreme cases. (I don't know the limit on HP, but 1000 will actually work.) Note that, if the dummy's speed is set to zero, the '''OnAction()''' hook won't trigger.&lt;br /&gt;
&lt;br /&gt;
Now we can place the dummy on the map and go to town. However, this dummy can still be pushed around if it takes enough damage, and there's a good chance we don't want to chase this thing all across the map. There are two ways to add some knockback prevention:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Items{&lt;br /&gt;
    name = &amp;quot;dummysuit&amp;quot;&lt;br /&gt;
    weight = 0,&lt;br /&gt;
    sprite = 0,&lt;br /&gt;
    type = ITEMTYPE_ARMOR,&lt;br /&gt;
    desc = &amp;quot;for dummy&amp;quot;,&lt;br /&gt;
    knockmod = -100,&lt;br /&gt;
    flags = {IF_NODROP},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Beings{&lt;br /&gt;
    name   = &amp;quot;dummy&amp;quot;,&lt;br /&gt;
    ....&lt;br /&gt;
    OnCreate = function(self)&lt;br /&gt;
        self.eq.armor = item.new(&amp;quot;dummysuit&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first method is to create a [[Modding:Tutorial/Custom Items|custom item]], either armor or boots, that provides 100% knockback reduction, and then place the armor/boots in the dummy's armor/boots equipment slot on creation. The &amp;quot;IF_NODROP&amp;quot; flag is there so that, no matter what kind of dummy you create, it will never let the armor drop (allowing the player to wear it).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Beings{&lt;br /&gt;
    name   = &amp;quot;dummy&amp;quot;,&lt;br /&gt;
    ....&lt;br /&gt;
    OnCreate = function(self)&lt;br /&gt;
        self.bodybonus = 100&lt;br /&gt;
    end&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The second method is to alter the dummy's ''bodybonus'' property on creation, setting it to a very high amount so that only extreme amounts of damage will ever cause movement. ''bodybonus'' works like the Badass trait, so each point will prevent X damage from causing knockback, where X depends on the damage type (usually 12, 7 for fire). (Note that ''bodybonus'' accepts only ShortInt values, which range from -128 to 127.) This isn't as guaranteed as the first method, but requires fewer lines of code to execute and doesn't add a new item definition.&lt;br /&gt;
&lt;br /&gt;
Now that we have an indestructible, immovable being, we can try making it useful. One fairly simple possibility is to have it spawn with an item and have it act as a decoy for other enemies to attack while you run from them. Here is one way to set it up:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Items{&lt;br /&gt;
    name = &amp;quot;hologram projector&amp;quot;,&lt;br /&gt;
    id = &amp;quot;holo&amp;quot;,&lt;br /&gt;
    level = 10,&lt;br /&gt;
    weight = 30,&lt;br /&gt;
    sprite = 0,&lt;br /&gt;
    desc = &amp;quot;Creates a virtual replica of yourself. These hellish buffoons won't know the difference!&amp;quot;&lt;br /&gt;
    type = ITEMTYPE_PACK,&lt;br /&gt;
&lt;br /&gt;
    OnUse = function()&lt;br /&gt;
        local p = player:get_position()&lt;br /&gt;
        local a = area.around(p,1)&lt;br /&gt;
        Level.area_summon(a,&amp;quot;decoy&amp;quot;,1)&lt;br /&gt;
        return(true)&lt;br /&gt;
    end,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Beings{&lt;br /&gt;
    name   = &amp;quot;decoy&amp;quot;,&lt;br /&gt;
    id     = &amp;quot;decoy&amp;quot;,&lt;br /&gt;
    ascii  = &amp;quot;@&amp;quot;,&lt;br /&gt;
    color  = LIGHTGRAY,&lt;br /&gt;
    desc   = &amp;quot;It looks just like you!&amp;quot;,&lt;br /&gt;
    soundID = &amp;quot;soldier&amp;quot;,&lt;br /&gt;
    sprite = 0,&lt;br /&gt;
    weight = 0,&lt;br /&gt;
    danger = 0,&lt;br /&gt;
    minLev = 0,&lt;br /&gt;
    group =  1,&lt;br /&gt;
    speed  = 40,&lt;br /&gt;
    flags  = {BF_INV},&lt;br /&gt;
&lt;br /&gt;
    OnCreate = function(self)&lt;br /&gt;
        self.bodybonus = 100&lt;br /&gt;
        self.scount = 4000&lt;br /&gt;
    end,&lt;br /&gt;
&lt;br /&gt;
    OnAction = function(self)&lt;br /&gt;
        self:kill()&lt;br /&gt;
    end,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The item, called ''holo'', uses '''Level.area_summon()''' to spawn a single dummy being adjacent to the player. The area is found by first getting the coordinate of the player using '''player:get_position()''', and then using that coordinate to create a square centered around that coordinate with '''area.around()'''.&lt;br /&gt;
&lt;br /&gt;
The being, called ''decoy'', is very similar to our original dummy, although a few things have changed in order to make it work properly:&lt;br /&gt;
&lt;br /&gt;
*First, we set ''speed'' to a non-zero but small number. This will serve as the decoy's timer.&lt;br /&gt;
*Next, we change the decoy's scount on creation to 4000. Since each turn increases ''scount'' by ''speed'', and beings take actions when their ''scount'' is 5000, we can calculate that (5000-4000)/40 = 25, which is the amount of game seconds that the being will exist before taking an action.&lt;br /&gt;
*Finally, we modify the decoy's '''OnAction()''' hook to remove itself from the map using the '''being:kill()''' method. This is used instead of the '''Level.clear_being()''' method so that it doesn't interfere with 100% completions (since any being added to the map will add one to the total enemies on the map).&lt;br /&gt;
*In addition to the changes above, we also set ''group'' to 1, same as the player's, so that all enemies will attack the decoy just as they would the player. (To be fair, I don't know how well this works with the enemy AI, but this is the only way for this to work short of very specific AI modifications.)&lt;br /&gt;
&lt;br /&gt;
The end result is that we have an item that causes a decoy to spawn next to the player, which lasts for 25 turns and will be attacked by enemies before disappearing. It should work in theory, although the extent to which enemies will attack a pacifist decoy aren't well-known. It is likely that you'll need not to attack enemies yourself to get the best use out of it.&lt;br /&gt;
&lt;br /&gt;
===Multi-form Beings===&lt;br /&gt;
A multi-form being is one that changes while you are fighting it. This can come in a variety of forms (HP loss, actions taken, level-specific triggers) and can cause a variety of changes (stat modifications, weapon changes, new abilities). They are most often created for the purpose of &amp;quot;boss fights&amp;quot; or some similarly final combat in the level or game. Let's begin by setting up the prototype for a multi-form being:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Beings{&lt;br /&gt;
    name            = &amp;quot;mecha-baron&amp;quot;,&lt;br /&gt;
    name_plural     = &amp;quot;mecha-barons&amp;quot;,&lt;br /&gt;
    id              = &amp;quot;mechbaron&amp;quot;,&lt;br /&gt;
    ascii           = &amp;quot;H&amp;quot;,&lt;br /&gt;
    sprite          = 0,&lt;br /&gt;
    color           = LIGHTMAGENTA,&lt;br /&gt;
    sound_id        = &amp;quot;arachno&amp;quot;,&lt;br /&gt;
    desc            = &amp;quot;Looks like someone found one of the gunner 'bots.&amp;quot;&lt;br /&gt;
    kill_desc       = &amp;quot;gunned down by a mecha-baron&amp;quot;,&lt;br /&gt;
    kill_desc_melee = &amp;quot;smashed to dust by a mecha-baron&amp;quot;,&lt;br /&gt;
    weight          = 1&lt;br /&gt;
    danger          = 15,&lt;br /&gt;
    minLev          = 20,&lt;br /&gt;
    corpse          = &amp;quot;baron&amp;quot;,&lt;br /&gt;
    HP              = 140,&lt;br /&gt;
    armor           = 0,&lt;br /&gt;
    res_bullet      = 25,&lt;br /&gt;
    res_melee       = 50,&lt;br /&gt;
    res_shrapnel    = 25,&lt;br /&gt;
    weapon          = {&lt;br /&gt;
        damage = &amp;quot;1d10&amp;quot;,&lt;br /&gt;
        damagetype = DAMAGE_BULLET,&lt;br /&gt;
        fire = 12,&lt;br /&gt;
        shots = 10,&lt;br /&gt;
        soundID = &amp;quot;chaingun&amp;quot;,&lt;br /&gt;
        missile = &amp;quot;chaingun&amp;quot;,&lt;br /&gt;
    }&lt;br /&gt;
    toDam           = 15,&lt;br /&gt;
    toHit           = 1,&lt;br /&gt;
    toHitMelee      = -1,&lt;br /&gt;
    attackchance    = 40,&lt;br /&gt;
    vision          = 9,&lt;br /&gt;
    speed           = 80,&lt;br /&gt;
    ai_type         = &amp;quot;melee_ranged_ai&amp;quot;,&lt;br /&gt;
    flags           = {},&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea behind this multi-form being is that a Baron of hell is inside some kind of vehicle (typically known as a &amp;quot;mech&amp;quot;) which augments its fighting power. It has the equivalent of an assault cannon for the attack and never runs out of ammo, though is slightly less accurate to compensate), and a remarkable amount of health and resistances. However, the baron operating this machine isn't quite as skilled a trained marine or the mech's own AI would be, so it's fairly slow at the same time.&lt;br /&gt;
&lt;br /&gt;
Now let's add a second form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
Beings{&lt;br /&gt;
    name            = &amp;quot;mecha-baron&amp;quot;,&lt;br /&gt;
    ....&lt;br /&gt;
&lt;br /&gt;
    OnCreate = function(self)&lt;br /&gt;
        self:add_property(&amp;quot;rogue&amp;quot;,false)&lt;br /&gt;
    end,&lt;br /&gt;
&lt;br /&gt;
    OnAction = function(self)&lt;br /&gt;
        if self.hp &amp;lt; 70 and not self.rogue then&lt;br /&gt;
            self.hp = 70&lt;br /&gt;
            self.name = &amp;quot;rogue mech&amp;quot;&lt;br /&gt;
            self.color = DARKGRAY&lt;br /&gt;
            self.weapon.fire = 10&lt;br /&gt;
            self.tohit = 3&lt;br /&gt;
            self.speed = 100&lt;br /&gt;
            self.group = 2&lt;br /&gt;
            self.rogue = true&lt;br /&gt;
            self:msg(&amp;quot;Pilot dead: massacre mode activated.&amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
    end,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea behind the second form is that the player managed to kill the baron inside of the vehicle, but now that it no longer has a living pilot, the mech begins shooting everything around. In order to implement this form, we add a trigger property called ''rogue'' which is set to false upon creation. Once the mecha-baron's HP dips below 70 while ''rogue'' is false, we set the HP back to 70, change some properties like name, color, and combat stats, then set ''rogue'' to true (so that it doesn't trigger again). ''group'' is also set to a value different from normal enemies and the player, which causes the being to now attack and be attacked by everything. Finally, we get a message indicating that this has occured (assuming the player is in sight of the mecha-baron when this happens).&lt;br /&gt;
&lt;br /&gt;
Note that, when the rogue mech finally dies, it will drop a baron corpse: the mech itself cannot be revived, but the mangled body inside of it can, which is why we set this. If you wanted to be creative, you could drop the corpse when the baron &amp;quot;dies&amp;quot;, although you should be careful about where it's dropped and if it should be dropped (for instance, corpses typically don't replace fluid or door tiles).&lt;br /&gt;
&lt;br /&gt;
===Special Abilities===&lt;br /&gt;
Even in the base game, there are a variety of special abilities that enemies use. Typically, these are handled either through flags or the '''OnAction()''' hook.&lt;br /&gt;
&lt;br /&gt;
While there is really only one flag that takes care of in-game abilities for enemies (the first one here), there are plenty that correspond to benefits and disadvantages given to the player.&lt;br /&gt;
&lt;br /&gt;
*'''Immunity to environmental damage''', namely walking on acid and lava tiles, is set with the BF_ENVIROSAFE flag. This is also the same flag used with the player activates an [[envirosuit pack]]. Custom hazard cells must check for this flag during the '''OnEnter()''' hook for it to apply (at which point the tile can deal whatever damage you want it to).&lt;br /&gt;
*'''Berserk boosts''' are handled with the BF_BERSERK flag (not to be confused with BF_BERSERKER).&lt;br /&gt;
*'''Invulnerability to all damage''' comes from the BF_INV, as described earlier.&lt;br /&gt;
*'''Increased ammo capacity''' is gained using BF_BACKPACK. This only works at a +40% bonus: if you want full control (and, to some extent, better handling of ammo in your inventory when you get this effect) you'll want to design a custom script that changes ''ammomax'' of all ITEMTYPE_AMMO items, then systematically rearrange the player's inventory when the effect activates.&lt;br /&gt;
*'''Regeneration''' can be handled through the BF_REGENERATE flag, which works once per second (rather than action). However, the benefit only applies for up to 20 HP.&lt;br /&gt;
*'''Class bonuses''' have a few flags as well:&lt;br /&gt;
**BF_POWERBONUS increases all base-game powerup durations by 50%. If you want to use both base and custom powerups, you'll have to check for this flag on any customs during the '''OnUse()''' flag that applies an effect (at which point you can change the duration to whatever you want). When modding with only custom powerups, this flag is superfluous.&lt;br /&gt;
**BF_STAIRSENSE counts all tiles with the CF_STAIRS flag as permanently visible.&lt;br /&gt;
**BF_INSTAUSE reduces all time spent using ITEMTYPE_PACK items to a single turn, rather than the default 1.0s (10 turns).&lt;br /&gt;
**BF_MAPEXPERT is what makes [[Computer Map|Computer Maps]] act like [[Tracking Map|Tracking Maps]]. For modding, this is mostly superfluous.&lt;br /&gt;
*'''Trait bonuses''' that don't include a simple change in stats (such the ''bonus'' properties) are typically given through flags:&lt;br /&gt;
**[[Juggler]] uses the BF_QUICKSWAP flag&lt;br /&gt;
**[[Berserker]] uses the BF_BERSERKER flag (attack-based benefits only apply to melee hits)&lt;br /&gt;
**[[Dualgunner]] uses the BF_DUALGUN flag (benefits only apply if both weapons in the weapon and prepared slots have the IF_PISTOL flag)&lt;br /&gt;
**[[Dodgemaster]] uses the BF_MASTERDODGE flag&lt;br /&gt;
**[[Intuition]] uses several flags:&lt;br /&gt;
***BF_POWERSENSE reveals powerups&lt;br /&gt;
***BF_BEINGSENSE reveals enemies (using the intuition color/symbol from config.lua)&lt;br /&gt;
***BF_LEVERSENSE1 and BF_LEVERSENSE2 provide more detailed information about levers. [[Modding:Tutorial/Custom Items#Lever (_LEVER)|Custom levers]] can be made to take advantage of these flags, if you so choose to.&lt;br /&gt;
**[[Shottyman]] uses the BF_SHOTTYMAN flag (benefits only apply to items with the IF_SHOTGUN flag)&lt;br /&gt;
**[[Vampyre]] uses the BF_VAMPYRE flag (benefits only apply to melee kills)&lt;br /&gt;
**[[Army of the Dead]] uses the BF_ARMYDEAD flag. (benefits only apply to weapons that use DAMAGE_SHRAPNEL)&lt;br /&gt;
**[[Survivalist]] uses two flags:&lt;br /&gt;
***BF_HARDY allows protection and resistances to reduce damage taken to zero. On Survivalist, this only works 50% of the time, but the BF_HARDY flag is hard-coded to work in every case.&lt;br /&gt;
***BF_MEDPLUS allows med-packs to heal above 100%. Dependings on how you create your own health supplies, this may be a superfluous flag.&lt;br /&gt;
**[[Blademaster]] uses the BF_CLEAVE flag (benefits only apply to melee kills)&lt;br /&gt;
**[[Gun Kata]] uses the BF_GUNKATA flag (benefits only apply to weapons with the IF_PISTOL flag)&lt;br /&gt;
**[[Sharpshooter]] uses the BF_PISTOLMAX flag (benefits only apply to weapons with the IF_PISTOL flag)&lt;br /&gt;
**[[Fireangel]] uses the BF_FIREANGEL flag&lt;br /&gt;
**[[Scavenger]] uses the BF_SCAVENGER flag. Since non-player beings don't know how to unload items, this is useless on any being but the player.&lt;br /&gt;
*'''Challenge perks''' can be arranged through some flags:&lt;br /&gt;
**[[Angel of Impatience]] is caused by the BF_IMPATIENT flag.&lt;br /&gt;
**The [[Angel of Darkness]] no-exploration effect is caused by BF_DARKNESS. Note that, if applied in mid-level, it only prevents other tiles from being counted as explored.&lt;br /&gt;
**The [[Angel of Max Carnage]] max-damage effect is caused by BF_MAXDAMAGE.&lt;br /&gt;
**[[Angel of Masochism]] is caused by BF_NOHEAL.&lt;br /&gt;
&lt;br /&gt;
===&amp;quot;Smart&amp;quot; Beings===&lt;br /&gt;
Normally monsters act solely to kill the player. There are, however, some flags that allow beings to act more intelligently while they move around, without needing to define your own AI:&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;BF_USESITEMS&amp;quot; allows the being to pick up items with the &amp;quot;IF_AIHEALPACK&amp;quot; flag. Armor will be immediately equipped on pickup, but the being will not carry more than one armor at a time. Consumables will be used when the being is below 50% of their health.&lt;br /&gt;
*&amp;quot;BF_OPENDOORS&amp;quot; allows the being to open doors, if their path would require them to move into a door.&lt;br /&gt;
*&amp;quot;BF_DISTANCE&amp;quot; is a flag that causes the being, as opposed to normal movement, not to seek engagement with its attacker. Useful for enemies that don't have much of a melee weapon but a powerful ranged weapon.&lt;br /&gt;
*&amp;quot;BF_CHARGE&amp;quot; allows the being to enter hazardous tiles when moving around. Useful for enemies that you set immune to hazardous damage (through &amp;quot;BF_ENVIROSAFE&amp;quot;).&lt;br /&gt;
*&amp;quot;BF_HUNTING&amp;quot; sets the being to precisely target the player, regardless of where the player is. Note that this flag does not necessarily pick the best path, so beings can stll become &amp;quot;stuck&amp;quot;. Unlike other flags here, BF_HUNTING works with lua-scripted AI.&lt;br /&gt;
&lt;br /&gt;
These flags are still somewhat limited with regards to being intelligence, but they cover a variety of needs without having to hassle with more advanced setups.&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	<entry>
		<id>https://drl.chaosforge.org/wiki/Modding:Tutorial/Constructing_a_Map</id>
		<title>Modding:Tutorial/Constructing a Map</title>
		<link rel="alternate" type="text/html" href="https://drl.chaosforge.org/wiki/Modding:Tutorial/Constructing_a_Map"/>
				<updated>2025-08-11T12:28:37Z</updated>
		
		<summary type="html">&lt;p&gt;Epyon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There are endless possibilities when it comes to modding DRL, whether it be custom enemies and items, or additional special levels, or maybe themes that depend on what day of the week it is. However, much of this can be difficult to understand, let alone create, if you are unfamiliar with programming techniques. For those of you simply seeking to create a single level, leaving the core elements of the game intact, there is a very easy method of doing this, especially with the advent of modules.&lt;br /&gt;
&lt;br /&gt;
==Initial Setup==&lt;br /&gt;
&lt;br /&gt;
If you are creating a mod, the first thing necessary for DRL to recognize it is a directory that is the identifier of your mod, along with a .module at the end: this would be placed in the &amp;quot;modules&amp;quot; directory, which exists wherever your DRL directory is. For instance, if I were creating a mod that I would identify as &amp;quot;coolmap&amp;quot; (and assuming that my DRL directory were in something like C:/Games), the path to the module files would look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;C:/Games/DRL/modules/coolmap.module&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that this identifier is not necessarily the NAME of your map, it is simply a way to distinguish it from other modules.&lt;br /&gt;
&lt;br /&gt;
After we have created this directory, there are two necessary lua files that must be in it: main.lua, which acts as the file that initializes all of the module's data; and module.lua, which provides information about the module itself. main.lua will contain everything important to the actual modding part of this tutorial, but we shall look at module.lua first.&lt;br /&gt;
&lt;br /&gt;
If you are unfamiliar with creating lua script files, it is as simple as creating a text file and changing the file extension to &amp;quot;.lua&amp;quot;. Refer to the Tutotial main page for more information.&lt;br /&gt;
&lt;br /&gt;
==module.lua==&lt;br /&gt;
&lt;br /&gt;
module.lua is a very short script, containing only what is called a metadata table, or a table that holds information about the mod. Every module.lua should look have a base like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
module = {&lt;br /&gt;
    id          = &amp;quot;&amp;quot;,        --identifier of the module (same as the folder sans '.module')&lt;br /&gt;
    name        = &amp;quot;&amp;quot;,        --name of module as it appears in the Custom Game menu&lt;br /&gt;
    author      = &amp;quot;&amp;quot;,        --your name/gamertag/nickname/alias&lt;br /&gt;
    webpage     = &amp;quot;&amp;quot;,        --link to your page (use 'none' if you don't have one)&lt;br /&gt;
    version     = {0,0,0},   --version of the mod itself (first version is typically {0,1,0})&lt;br /&gt;
    drlver      = {0,0,0,0}, --version of DRL that module was made for (e.g., {0,9,9,4})&lt;br /&gt;
    type        = &amp;quot;single&amp;quot;,  --module type (currently only &amp;quot;single&amp;quot; works)&lt;br /&gt;
    description = &amp;quot;&amp;quot;,        --explains mod, though you could put whatever you want here&lt;br /&gt;
    difficulty  = true,      --allows player to set difficulty (false forces ITYTD)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Feel free to copy and paste this into your module.lua, then fill in the information as necessary.&lt;br /&gt;
&lt;br /&gt;
==main.lua==&lt;br /&gt;
&lt;br /&gt;
main.lua is the core of your module, containing all of the necessary components to make the mod run as you would like it to. To start, every main.lua requires the following line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
core.declare(&amp;quot;module_id&amp;quot;, {} ) --replace module_id with your module's actual id&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This declares a module table that you will use to store all of the module-ranging components. In the case of single levels (currently the only mod type available), this essentially replaces the [[Modding:Level|Level object]] for the purposes of creating engine hooks that depend on events that occur within the single level. These are the following engine hooks that your module can use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function module_id.run() end       --works just like Level.Create() (initialize map/name/spawn point/etc)&lt;br /&gt;
function module_id.OnEnter() end   --triggers immediately after .run(), when player enters the map&lt;br /&gt;
function module_id.OnTick() end    --triggers every game turn&lt;br /&gt;
function module_id.OnKill() end    --triggers whenever a being other than yourself dies&lt;br /&gt;
function module_id.OnKillAll() end --triggers whenever all beings other than yourself are dead&lt;br /&gt;
function module_id.OnExit() end    --triggers when player exits the map (for instance, decsending stairs)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you choose not to use an engine hook, you don't need to include it in the script, but there's no harm in writing an empty hook in there, either.&lt;br /&gt;
&lt;br /&gt;
We will now provide some very basic examples of each engine hook so you get an idea of how they can be used. The module's identifier will be &amp;quot;blank&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===.run()===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function blank.run()&lt;br /&gt;
    Level.name = &amp;quot;Blank Map&amp;quot; --name of map as it appears in lower-right corner of HUD&lt;br /&gt;
    Level.name_number = 0    --shows &amp;quot;LevX&amp;quot; where X is value: use 0 to remove entirely&lt;br /&gt;
    Level.fill(&amp;quot;wall&amp;quot;)      --necessary step, use whatever wall you will mostly use&lt;br /&gt;
&lt;br /&gt;
    --matches all characters on map to an object_id&lt;br /&gt;
    local translation = {&lt;br /&gt;
    [&amp;quot;.&amp;quot;] = &amp;quot;floor&amp;quot;,&lt;br /&gt;
    [&amp;quot;#&amp;quot;] = &amp;quot;wall&amp;quot;,&lt;br /&gt;
    [&amp;quot;&amp;gt;&amp;quot;] = &amp;quot;stairs&amp;quot;,&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    --the map itself&lt;br /&gt;
    local map = [[&lt;br /&gt;
##############################################################################&lt;br /&gt;
#............................................................................#&lt;br /&gt;
#............................................................................#&lt;br /&gt;
#............................................................................#&lt;br /&gt;
#............................................................................#&lt;br /&gt;
#............................................................................#&lt;br /&gt;
#............................................................................#&lt;br /&gt;
#............................................................................#&lt;br /&gt;
#............................................................................#&lt;br /&gt;
#...........................................&amp;gt;................................#&lt;br /&gt;
#............................................................................#&lt;br /&gt;
#............................................................................#&lt;br /&gt;
#............................................................................#&lt;br /&gt;
#............................................................................#&lt;br /&gt;
#............................................................................#&lt;br /&gt;
#............................................................................#&lt;br /&gt;
#............................................................................#&lt;br /&gt;
#............................................................................#&lt;br /&gt;
#............................................................................#&lt;br /&gt;
##############################################################################&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
    Level.place_tile(translation,map,1,1) --this is the map-creation step&lt;br /&gt;
    Generator.set_permanence( area.FULL )&lt;br /&gt;
    Level.player(39,10)                   --player is placed at this coordinate&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''run()''' deals with the absolutely necessary pieces if you want the module to work at all. Here we define the level's in-game name, create the map, and add the player. There are two important variables we define:&lt;br /&gt;
*''translation'' is a table of all object ids that will be placed on the map, along with the symbols that define them on said map. You can use any symbol you want to define an object (for instance, using [&amp;quot;y&amp;quot;] = &amp;quot;pwall&amp;quot;), just remember to place it on the map with that symbol. The symbols as they are used here will not affect how the actual objects appear in-game.&lt;br /&gt;
*''map'' is a string that corresponds to what the map should look like when it is initialized. Here we use double-square brackets (&amp;quot;&amp;lt;nowiki&amp;gt;[[&amp;lt;/nowiki&amp;gt;&amp;quot; and &amp;quot;&amp;lt;nowiki&amp;gt;]]&amp;lt;/nowiki&amp;gt;&amp;quot;), which takes every character between them and writes into a single string. You can start new lines as much as you want, but do NOT include spaces unless the space character is one of the symbols used in ''translation''.&lt;br /&gt;
&lt;br /&gt;
You can define ''translation'' and ''map'' whatever you want so long as '''Level.place_tile()''' calls them appropriately. The last two arguments define what x- and y-coordinates are used to begin the placing: since we are copying an entire map, we start from the upper-left tile (which is (1,1)).&lt;br /&gt;
&lt;br /&gt;
Finally, to make sure none of the border walls get destroyed, we include the Generator.set_permanence() function. Walls have a permanent flag that make them indestructible, and using this function you can set an area in which all tiles are given the flag. area.FULL is an area constant corresponding to the full extent of the map, thereby setting any tiles that can be made permanent tiles, into permanent tiles. (Floors cannot be made permanent, as they cannot take damage in the first place.)&lt;br /&gt;
&lt;br /&gt;
===.OnEnter()===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function blank.OnEnter()&lt;br /&gt;
    ui.msg(&amp;quot;Hello world!&amp;quot;)    --appears at the top of the screen&lt;br /&gt;
    player.inv:add(&amp;quot;shotgun&amp;quot;) --puts a shotgun in the player's inventory&lt;br /&gt;
    player.inv:add(&amp;quot;shell&amp;quot;)   --puts a shotgun shell (x8) in the player's inventory&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The '''OnEnter()''' hook has fairly limited uses, since it is only called once and doesn't do the crucial steps like making the map itself. For the most part, it is used to add messages at the start of the map, change around the player's inventory, and, depending on what else is going on in the map, initialize some timers or countdowns.&lt;br /&gt;
&lt;br /&gt;
===.OnTick()===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local countdown = 600   --set up a timer&lt;br /&gt;
local minute = 0        --set up a minute counter&lt;br /&gt;
local exit_check = true --set up a position check&lt;br /&gt;
&lt;br /&gt;
function blank.OnTick()&lt;br /&gt;
    if countdown == 0 then&lt;br /&gt;
        countdown = 600&lt;br /&gt;
        minute = minute + 1&lt;br /&gt;
        ui.msg(&amp;quot;Number of minutes passed: &amp;quot;.. minute)&lt;br /&gt;
    end&lt;br /&gt;
    countdown = countdown - 1&lt;br /&gt;
&lt;br /&gt;
    if player:get_position() == coord.new(45,10) and exit_check then&lt;br /&gt;
        ui.msg(&amp;quot;Leaving already?&amp;quot;)&lt;br /&gt;
        exit_check = false&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''OnTick()''' is, by far, the most extensive trigger of the module engine hooks, allowing you not only to set up time-specific events but also position-specific ones. In the example above, both cases are used:&lt;br /&gt;
&lt;br /&gt;
*A ''countdown'' variable starts at 600: whenever it reaches zero (as 60 game seconds have passed), ''countdown'' is reset, ''minute'' is incremented by one, and the game tells you how many minutes have passed.&lt;br /&gt;
*Whenever the player enters the same tile as the stairs (the stairs happen to be on (45,10)), the game sends a message, and then sets exit_check to false. Were this check not added, the message would display continuously for each turn that you stay in the tile (so it will keep displaying the message if you wait on the tile, for instance). However, this also means it will only display once, as there are no conditions in the code in which exit_check can be made true again.&lt;br /&gt;
&lt;br /&gt;
Setting up too many events in the '''OnTick()''' hook may cause some game slow-down, but it usually takes a monstrous amount of code (or some very iterative processes) before there is even a noticeable effect.&lt;br /&gt;
&lt;br /&gt;
===.OnKill()===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local killCount = 0 --set up a kill counter&lt;br /&gt;
&lt;br /&gt;
function blank.OnKill()&lt;br /&gt;
    killCount = killCount + 1 --increment the kill counter&lt;br /&gt;
&lt;br /&gt;
    --display messages dependent on kills&lt;br /&gt;
    if killCount == 1 then&lt;br /&gt;
        ui.msg(&amp;quot;You have killed 1 enemy.&amp;quot;)&lt;br /&gt;
    else ui.msg(&amp;quot;You have killed &amp;quot; .. killCount .. &amp;quot; enemies.&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    if killCount == 10 then&lt;br /&gt;
        ui.msg(&amp;quot;Wow, killing spree!&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''OnKill()''' lets you trigger events when an enemy is killed by you specifically. There are a number of possibilities you may want to try (adding to berserk time, increasing health, spawning new enemies, etc): this example displays a simple message whenever you kill something, and gives you a metaphorical pat on the back for ten kills.&lt;br /&gt;
&lt;br /&gt;
===.OnKillAll()===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function blank.OnKillAll()&lt;br /&gt;
    Level.summon(&amp;quot;former&amp;quot;,5)&lt;br /&gt;
    ui.msg(&amp;quot;They just keep coming!!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''OnKillAll()''' is like '''OnKill()''' but only triggers when everything on the map has died. This is how, for instance, [[Hell's Arena]] knows when to start the next wave of enemies (or when you're completely done). In this example, whenever you kill everything on the map, the game randomly spawns five former humans, essentially allowing this trigger to occur for as many times as the player wants to do so.&lt;br /&gt;
&lt;br /&gt;
===.OnExit()===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function blank.OnExit()&lt;br /&gt;
    ui.msg_enter(&amp;quot;Goodbye world!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''OnExit()''', just as with '''OnEnter()''', is limited in its uses when it comes to a single level. You can add some messages, maybe tidy up some variables for the mortem, but once the player is leaving there isn't much left with which to interact. (In this case, ui.msg_enter() is used in order to force a confirmation on the player: otherwise the message could very well be lost in the mortem bloodslide effect.)&lt;br /&gt;
&lt;br /&gt;
==Review==&lt;br /&gt;
&lt;br /&gt;
The following is a summation of all the lines of codes used to create the module.lua and main.lua scripts, with a few changes here and there to ensure that everything will run as intended (and a couple additions to make it more playable).&lt;br /&gt;
&lt;br /&gt;
{{:Modding:Tutorial/Constructing a Map/Source}}&lt;br /&gt;
&lt;br /&gt;
Source data: [http://dl.dropbox.com/u/54818507/blank.module.zip blank.module]&lt;/div&gt;</summary>
		<author><name>Epyon</name></author>	</entry>

	</feed>