Difference between revisions of "Modding:Module"

From DoomRL Wiki

Jump to: navigation, search
(Created page with some initial info on the module system)
 
m (Metadata: typo)
 
(9 intermediate revisions by 3 users not shown)
Line 1: Line 1:
Note: This page is related to DoomRL 0.9.9.4 modding. For information on 0.9.9.3 modding, check out the [http://old-wiki.chaosforge.org/wiki/index.php?title=Sandbox old wiki]. Keep in mind that, as 0.9.9.4 is as-of-yet unreleased, this information is subject to change.
 
 
 
A module is the DoomRL name for a mod. A module must contain a module.lua metadata file and a main.lua source file. It may also contain sounds, music, and ASCII art.
 
A module is the DoomRL name for a mod. A module must contain a module.lua metadata file and a main.lua source file. It may also contain sounds, music, and ASCII art.
  
Line 31: Line 29:
 
|-
 
|-
 
|style="text-align: right; vertical-align:top; padding-right: 2ex;"|'''string''' type
 
|style="text-align: right; vertical-align:top; padding-right: 2ex;"|'''string''' type
|Currently, this must be "single", as no other types are supported yet.
+
|This is the type of the module. Can currently be "single" or "episode".
 
|-style="background: #333;"
 
|-style="background: #333;"
 
|style="text-align: right; vertical-align:top; padding-right: 2ex;"|'''string''' description
 
|style="text-align: right; vertical-align:top; padding-right: 2ex;"|'''string''' description
Line 41: Line 39:
  
 
== Main ==
 
== Main ==
 +
Every module must also have a main.lua file directly in the module folder. This file will be loaded after the module is selected from the Custom Game menu. It must declare a global table (via [[core.declare]]) with the same name as the module's id. This table contains various functions that determine how the module works.
  
Every module must also have a main.lua file directly in the module folder. This file will be loaded after the module is selected from the Custom Game menu. It must declare a global table (via [[core.declare]]) with the same name as the module's id. This table contains various functions that determine how the module works. For single-type modules, the available hooks are precisely the [[Modding:Level|Level]] hooks, with a new function called ''run'' used to handle initial set up.
+
=== Engine Hooks ===
 +
Modules are defined by their hooks. In relation to the game itself (and aside from object-specific ones), there are three types of hooks:
  
== Data Files ==
+
*'''Chained''' hooks are defined across the various underpinnings of the game. By order of lowest to highest priority are: ''module'' hooks, which are written for a given "game"; challenge hooks, which are written for a particular challenge; and ''core'' hooks, which take place across all modules. In addition to the normal priorities, chained hooks defined at the module level (at least) always override object-specific hooks when applicable.
 +
*'''Level''' hooks are defined for a particular level. All chained hooks are also level hooks, but any of those hooks defined within a level are given lowest priority on the chain.
 +
*'''Global''' hooks are defined for an entire module. All chained hooks and level hooks are also global hooks. Global hooks are defined automatically at the ''core'' priority level unless manually altered.
  
Sound files used by a module must be included in a subdirectory called ''sound'' of the main module folder. These files are automatically loaded when the module is run even if they aren't referenced by DoomRL's config file. Their lua string ids correspond to their file names (without any file type extension).
+
{|class="wikitable" style="border: 2px solid darkred; border-spacing: 0; font-size: 90%; margin: 0.25em 0.5em;"
 +
! colspan="2" style="background: darkred; color: yellow; font-size: 120%; text-align: center"|'''Chained Hooks'''
 +
{{Table2Col
 +
  |es=background: #333;
 +
  |c1=font-weight:bold; text-align:right; vertical-align:top; padding:0px 2px;
 +
  |c2=padding:0px 2px;
 +
  |void|[[#chained_OnCreate|OnCreate]]()
 +
  |void|[[#chained_OnDie|OnDie]]()
 +
  |boolean|[[#chained_OnDieCheck|OnDieCheck]]()
 +
  |void|[[#chained_OnKillAll|OnKillAll]]()
 +
  |void|[[#chained_OnFire|OnFire]]()
 +
  |void|[[#chained_OnFired|OnFired]]()
 +
  |void|[[#chained_OnPickup|OnPickup]]()
 +
  |boolean|[[#chained_OnPickupCheck|OnPickupCheck]]()
 +
  |void|[[#chained_OnFirstPickup|OnFirstPickup]]()
 +
  |void|[[#chained_OnUse|OnUse]]()
 +
  |boolean|[[#chained_OnUseCheck|OnUseCheck]]()
 +
  |}}
 +
|}
 +
 
 +
{{Anchor|chained_OnCreate}}
 +
;OnCreate()
 +
:Called whenever any thing is created on the map.
 +
----
 +
{{Anchor|chained_OnDie}}
 +
;OnDie()
 +
:Called whenever any being is destroyed on the map.
 +
----
 +
{{Anchor|chained_OnDieCheck}}
 +
;OnDieCheck() → '''boolean'''
 +
:Called whenever any being's HP is reduced to zero on the map, before [[Modding:Being|being:kill()]] is called.
 +
----
 +
{{Anchor|chained_OnKillAll}}
 +
;OnKillAll()
 +
:Called whenever there are no beings left on the map (other than the player).
 +
----
 +
{{Anchor|chained_OnFire}}
 +
;OnFire()
 +
:Called whenever a ranged weapon is set to fire on the map, but before the missile is created.
 +
----
 +
{{Anchor|chained_OnFired}}
 +
;OnFired()
 +
:Called whenever a ranged weapon is fired on the map, immediately after all firing consequences (damage, knockback, etc) have ended.
 +
----
 +
{{Anchor|chained_OnPickup}}
 +
;OnPickup()
 +
:Called whenever an item is picked up on the map.
 +
----
 +
{{Anchor|chained_OnPickupCheck}}
 +
;OnPickupCheck() → '''boolean'''
 +
:Called whenever a being attempts to pick up an item on the map.
 +
----
 +
{{Anchor|chained_OnFirstPickup}}
 +
;OnFirstPickup()
 +
:Called whenever an item is picked up on the map by a being for the first time.
 +
----
 +
{{Anchor|chained_OnUse}}
 +
;OnUse()
 +
:Called whenever an item is used on the map.
 +
----
 +
{{Anchor|chained_OnUseCheck}}
 +
;OnUsePickup() → '''boolean'''
 +
:Called whenever a being attempts to pick up an item on the map.
 +
----
 +
 
 +
{|class="wikitable" style="border: 2px solid darkred; border-spacing: 0; font-size: 90%; margin: 0.25em 0.5em;"
 +
! colspan="2" style="background: darkred; color: yellow; font-size: 120%; text-align: center"|'''Level Hooks'''
 +
{{Table2Col
 +
  |es=background: #333;
 +
  |c1=font-weight:bold; text-align:right; vertical-align:top; padding:0px 2px;
 +
  |c2=padding:0px 2px;
 +
  |void|[[#level_OnEnter|OnEnter]]()
 +
  |void|[[#level_OnTick|OnTick]]()
 +
  |void|[[#level_OnKill|OnKill]]()
 +
  |void|[[#level_OnExit|OnExit]]()
 +
  |boolean|[[#level_OnCompletedCheck|OnCompletedCheck]]()
 +
  |}}
 +
|}
 +
 
 +
{{Anchor|level_OnEnter}}
 +
;OnEnter()
 +
:Called whenever the player enters the map. This is unchained from the item object's OnEnter hook.
 +
----
 +
{{Anchor|level_OnTick}}
 +
;OnTick()
 +
:Called every turn (0.1 game seconds) It is advised that specific conditions are used to prevent slowdown.
 +
----
 +
{{Anchor|level_OnKill}}
 +
;OnKill()
 +
:Called whenever any being is killed on the map. This is unchained from the item object's OnKill hook.
 +
----
 +
{{Anchor|level_OnExit}}
 +
;OnExit()
 +
:Called whenever the player exits the map.
 +
----
 +
{{Anchor|level_OnCompletedCheck}}
 +
;OnCompletedCheck() → '''boolean'''
 +
:Called whenever the player exits the map: if the level is determined to be cleared by unique conditions, or if there are no beings on the map other than the player, then this returns true.
 +
----
 +
 
 +
{|class="wikitable" style="border: 2px solid darkred; border-spacing: 0; font-size: 90%; margin: 0.25em 0.5em;"
 +
! colspan="2" style="background: darkred; color: yellow; font-size: 120%; text-align: center"|'''Global Hooks'''
 +
{{Table2Col
 +
  |es=background: #333;
 +
  |c1=font-weight:bold; text-align:right; vertical-align:top; padding:0px 2px;
 +
  |c2=padding:0px 2px;
 +
  |void|[[#global_OnLoadBase|OnLoadBase]]()
 +
  |void|[[#global_OnLoad|OnLoad]]()
 +
  |void|[[#global_OnLogo|OnLogo]]()
 +
  |void|[[#global_OnOnCreatePlayer|OnCreatePlayer]]()
 +
  |void|[[#global_OnIntro|OnIntro]]()
 +
  |void|[[#global_OnCreateEpisode|OnCreateEpisode]]()
 +
  |void|[[#global_OnLoaded|OnLoaded]]()
 +
  |void|[[#global_OnGenerate|OnGenerate]]()
 +
  |void|[[#global_OnPreLevelUp|OnPreLevelUp]]()
 +
  |void|[[#global_OnLevelUp|OnLevelUp]]()
 +
  |void|[[#global_OnOnWinGame|OnWinGame]]()
 +
  |void|[[#global_OnMortem|OnMortem]]()
 +
  |void|[[#global_OnMortemPrint|OnMortemPrint]]()
 +
  |void|[[#global_OnUnLoad|OnUnLoad]]()
 +
  |}}
 +
|}
 +
{{Anchor|global_OnLoadBase}}
 +
;OnLoadBase()
 +
:Called whenever either the base game or a total conversion module is loaded. This is the very first hook called for a module.
 +
----
 +
{{Anchor|global_OnLoad}}
 +
;OnLoad()
 +
:Called whenever a module is loaded. This occurs immediately after OnLoadBase (if it is called).
 +
----
 +
{{Anchor|global_OnLogo}}
 +
;OnLogo()
 +
:Called immediately after the module is loaded, but before the menu is created. In the base game this is used to create the DooM title graphic.
 +
----
 +
{{Anchor|global_OnCreatePlayer}}
 +
;OnCreatePlayer()
 +
:Called immediately after the player has selected their challenge and/or difficulty.
 +
----
 +
{{Anchor|global_OnIntro}}
 +
;OnIntro()
 +
:Called immediately the player has finished selecting a name and traits. In the base game this is used to create the introductory plot screens.
 +
----
 +
{{Anchor|global_OnCreateEpisode}}
 +
;OnCreateEpisode()
 +
:Called immediately after OnIntro (if it is called). This only works with episode and total conversion module types.
 +
----
 +
{{Anchor|global_OnLoaded}}
 +
;OnLoaded()
 +
:Called immediately before the module starts (that is, with the player on the map).
 +
----
 +
{{Anchor|global_OnGenerate}}
 +
;OnGenerate()
 +
:Called whenever a random map is created (that is, whenever a level is not called for a particular floor). This only works with episode and total conversion module types.
 +
----
 +
{{Anchor|global_OnPreLevelUp}}
 +
;OnPreLevelUp()
 +
:Called whenever the player levels up, but before they pick a trait.
 +
----
 +
{{Anchor|global_OnLevelUp}}
 +
;OnLevelUp()
 +
:Called whenever the player levels up, immediately after they pick a trait.
 +
----
 +
{{Anchor|global_OnWinGame}}
 +
;OnWinGame()
 +
:Called whenever the player wins the game. Simply, this is called using the [[Modding:Player|player:win()]] function.
 +
----
 +
{{Anchor|global_OnMortem}}
 +
;OnMortem()
 +
:Called immediately before the mortem is printed.
 +
----
 +
{{Anchor|global_OnMortem}}
 +
;OnMortemPrint()
 +
:Called alongside mortem printing. This is where all [[Modding:Player|player:mortem_print()]] functions should be used.
 +
----
 +
{{Anchor|global_OnMortem}}
 +
;OnUnLoad()
 +
:Called immediately after the mortem and high score screens are displayed and exited. For single module types, this returns the player to the base game module.
 +
 
 +
== Data Files ==
 +
Sound files used by a module must be included in a subdirectory called ''sound'' of the main module folder. These files are automatically loaded when the module is run even if they aren't referenced by DoomRL's config file. Their lua string ids correspond to their file names (without the file type extension). Sounds can only have a .wav extension.
  
Music files are handled analogously to sound files; they should be put in a directory called ''music''.
+
Music files are handled analogously to sound files; they should be put in a directory called ''music''. Music can have a .mid, .mp3, or .ogg extension.
  
ASCII art should be contained in a directory called ''ascii''. ASCII art files are text files that use [[valkyrie color escapes]] for coloring. By convention these files have the .asc extension. The name of an ASCII art file should be the same as the corresponding being's string id (or for custom player armor art, the same as the armor's string id). Currently, DoomRL only loads ASCII art from compiled modules.
+
ASCII art should be contained in a directory called ''ascii''. ASCII art files are text files that use [[Modding:Constants#Colors|valkyrie color escapes]] for coloring. By convention these files have the .asc extension. The name of an ASCII art file should be the same as the corresponding being's string id (or for custom player armor art, the same as the armor's string id). Currently, DoomRL only loads ASCII art from compiled modules.

Latest revision as of 11:51, 31 January 2012

A module is the DoomRL name for a mod. A module must contain a module.lua metadata file and a main.lua source file. It may also contain sounds, music, and ASCII art.

Modules can be either compiled or raw. Generally, modders distribute compiled modules. Compiled modules are files with the .wad extension. A .wad file contains all the information needed to run a module including sounds and music. A raw module is a folder with the .module extension. A raw module's folder contains all the files separately. Modders will typically have their own mod in raw format while they are developing it. A raw module can be compiled into a .wad file. In either case, modules should reside in the modules subdirectory of the main DoomRL folder.

Contents

Metadata

Every module must contain a module.lua metadata file. For raw modules, it should be directly in the module folder (not in any subdirectory). This file should define a global table called module to hold the metadata. This metadata is loaded when browsing mods in the Custom Game menu. The valid entries in the table are listed below.

Module Metadata
string id This is the name DoomRL internally use for the module. It should not be changed from version to version. The folder of a raw module must be named as the module's id with the ".module" extension. The .wad file of a compiled module must be named as the module's id with the ".wad" extension. By convention, only lowercase letters, numbers, and the underscore are used in a module's id.
string name This is the proper name of the module that will be displayed in the Custom Game menu.
string author This is the author's name (or alias). It will be displayed in the Custom Game menu.
string webpage This is the author's webpage. If you don't have a webpage, use "(none)". This will be displayed in the Custom Game menu.
integer list version This is the module's version number. The mod's version number should be updated whenever a new version is release, as future versions of DoomRL will use this to determine whether local mods are synced with the mod server. The format for a version is e.g. {1,0,0}.
integer list drlver This is the version of DoomRL that the module was designed to run with. For modules developed for 0.9.9.4, this will be {0,9,9,4}.
string type This is the type of the module. Can currently be "single" or "episode".
string description This is the description of the module that is displayed in the Custom Game menu. Keep in mind that space is somewhat limited. Also, this description will be used in the upcoming mod server, so it should be designed to make people want to play the module.
boolean difficulty This determines whether or not player's will get to choose a difficulty level after selecting the mod. If not, the default difficulty level is I'm Too Young To Die (at least for now... this may get changed to HNTR --tehtmi).

Main

Every module must also have a main.lua file directly in the module folder. This file will be loaded after the module is selected from the Custom Game menu. It must declare a global table (via core.declare) with the same name as the module's id. This table contains various functions that determine how the module works.

Engine Hooks

Modules are defined by their hooks. In relation to the game itself (and aside from object-specific ones), there are three types of hooks:

  • Chained hooks are defined across the various underpinnings of the game. By order of lowest to highest priority are: module hooks, which are written for a given "game"; challenge hooks, which are written for a particular challenge; and core hooks, which take place across all modules. In addition to the normal priorities, chained hooks defined at the module level (at least) always override object-specific hooks when applicable.
  • Level hooks are defined for a particular level. All chained hooks are also level hooks, but any of those hooks defined within a level are given lowest priority on the chain.
  • Global hooks are defined for an entire module. All chained hooks and level hooks are also global hooks. Global hooks are defined automatically at the core priority level unless manually altered.
Chained Hooks
void OnCreate()
void OnDie()
boolean OnDieCheck()
void OnKillAll()
void OnFire()
void OnFired()
void OnPickup()
boolean OnPickupCheck()
void OnFirstPickup()
void OnUse()
boolean OnUseCheck()

OnCreate()
Called whenever any thing is created on the map.

OnDie()
Called whenever any being is destroyed on the map.

OnDieCheck() → boolean
Called whenever any being's HP is reduced to zero on the map, before being:kill() is called.

OnKillAll()
Called whenever there are no beings left on the map (other than the player).

OnFire()
Called whenever a ranged weapon is set to fire on the map, but before the missile is created.

OnFired()
Called whenever a ranged weapon is fired on the map, immediately after all firing consequences (damage, knockback, etc) have ended.

OnPickup()
Called whenever an item is picked up on the map.

OnPickupCheck() → boolean
Called whenever a being attempts to pick up an item on the map.

OnFirstPickup()
Called whenever an item is picked up on the map by a being for the first time.

OnUse()
Called whenever an item is used on the map.

OnUsePickup() → boolean
Called whenever a being attempts to pick up an item on the map.

Level Hooks
void OnEnter()
void OnTick()
void OnKill()
void OnExit()
boolean OnCompletedCheck()

OnEnter()
Called whenever the player enters the map. This is unchained from the item object's OnEnter hook.

OnTick()
Called every turn (0.1 game seconds) It is advised that specific conditions are used to prevent slowdown.

OnKill()
Called whenever any being is killed on the map. This is unchained from the item object's OnKill hook.

OnExit()
Called whenever the player exits the map.

OnCompletedCheck() → boolean
Called whenever the player exits the map: if the level is determined to be cleared by unique conditions, or if there are no beings on the map other than the player, then this returns true.

Global Hooks
void OnLoadBase()
void OnLoad()
void OnLogo()
void OnCreatePlayer()
void OnIntro()
void OnCreateEpisode()
void OnLoaded()
void OnGenerate()
void OnPreLevelUp()
void OnLevelUp()
void OnWinGame()
void OnMortem()
void OnMortemPrint()
void OnUnLoad()

OnLoadBase()
Called whenever either the base game or a total conversion module is loaded. This is the very first hook called for a module.

OnLoad()
Called whenever a module is loaded. This occurs immediately after OnLoadBase (if it is called).

OnLogo()
Called immediately after the module is loaded, but before the menu is created. In the base game this is used to create the DooM title graphic.

OnCreatePlayer()
Called immediately after the player has selected their challenge and/or difficulty.

OnIntro()
Called immediately the player has finished selecting a name and traits. In the base game this is used to create the introductory plot screens.

OnCreateEpisode()
Called immediately after OnIntro (if it is called). This only works with episode and total conversion module types.

OnLoaded()
Called immediately before the module starts (that is, with the player on the map).

OnGenerate()
Called whenever a random map is created (that is, whenever a level is not called for a particular floor). This only works with episode and total conversion module types.

OnPreLevelUp()
Called whenever the player levels up, but before they pick a trait.

OnLevelUp()
Called whenever the player levels up, immediately after they pick a trait.

OnWinGame()
Called whenever the player wins the game. Simply, this is called using the player:win() function.

OnMortem()
Called immediately before the mortem is printed.

OnMortemPrint()
Called alongside mortem printing. This is where all player:mortem_print() functions should be used.

OnUnLoad()
Called immediately after the mortem and high score screens are displayed and exited. For single module types, this returns the player to the base game module.

Data Files

Sound files used by a module must be included in a subdirectory called sound of the main module folder. These files are automatically loaded when the module is run even if they aren't referenced by DoomRL's config file. Their lua string ids correspond to their file names (without the file type extension). Sounds can only have a .wav extension.

Music files are handled analogously to sound files; they should be put in a directory called music. Music can have a .mid, .mp3, or .ogg extension.

ASCII art should be contained in a directory called ascii. ASCII art files are text files that use valkyrie color escapes for coloring. By convention these files have the .asc extension. The name of an ASCII art file should be the same as the corresponding being's string id (or for custom player armor art, the same as the armor's string id). Currently, DoomRL only loads ASCII art from compiled modules.

Personal tools