modules.html 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <html>
  2. <head>
  3. <link href="../tutorial.css" rel="stylesheet" type="text/css">
  4. </head>
  5. <body>
  6. <div class="header">
  7. The NakedMud Tutorial :: Writing A Module
  8. </div>
  9. <!-- content starts here -->
  10. <div class="content-wrap"><div class="content-body-wrap"><div class="content">
  11. <div class="head">Introduction</div>
  12. <div class="info">
  13. There are three aspects of NakedMud's code that must be understood to
  14. efficiently write a mud using the codebase: modules, auxiliary data, and storage
  15. sets. Modules and auxiliary data allow programmers to organize their work by
  16. concept (e.g., combat-related functions and variables, magic-related stuff,
  17. etc...) rather than by data structure (e.g., all character variables, all room
  18. variables, etc...). This allows for easier distribution and organization of
  19. game function.
  20. <p></p>
  21. The third aspect - storage sets - is an attempt to provide a general
  22. format for saving and loading data from files, and eliminate much of the legwork
  23. that comes with reading and writing to files. It is also (more importantly) an
  24. attempt to ensure the addition of new information to data structures in the MUD
  25. never results in formatting conflicts within files.
  26. <p></p>
  27. This tutorial will provide a walkthrough on how to write a module, create
  28. auxiliary data, and store that data on character files. The same ideas can
  29. similarly be applied to rooms and objects.
  30. </div>
  31. <div class="head">Modules</div>
  32. <div class="info">
  33. Almost all new extensions to NakedMud are expected to be added through modules.
  34. In its most basic form, a module is a directory that contains src files, each
  35. united in some high-level, conceptual manner. For instance, you might have a
  36. module that contains all of the mechanics for combat, or another
  37. for all of the magic mechanics, or maybe another that adds commands with names
  38. that give your MUD the look and feel of a famous codebase like Circle or ROM.
  39. The main point is that modules organize the source code of your mud by concept.
  40. <p></p>
  41. Modules are easy to set up. Adding a happens like you would normally add code,
  42. except you have to make a new directory for everything that will be included
  43. in your module, and let the mud know you are adding a new module. Here, we will
  44. walk through the creation of a module that allows players to send and receive
  45. mail. In later sections, it will be built on to demonstrate how storage sets
  46. and auxiliary data work.
  47. </div>
  48. <div class="head">Preparing to Program</div>
  49. <div class="info">
  50. Before actually programming the mail module, a directory for it needs to be
  51. created. A few additions to the makefile are needed, and a call to the module's
  52. initialization procedure will have to be made when the mud boots up.
  53. <p></p>
  54. Enter your src directory, and make a new folder for the mail module. You will
  55. now have to let your Makefile know that the module exists. Open up Makefile in
  56. your src directory, and look for the line where optional modules are added to
  57. the variable, MODULES. The line you are searching for will look something like:
  58. <pre class="code">
  59. # optional modules go on this line
  60. MODULES += time socials alias help2
  61. </pre>
  62. To this list, add the name of the new module you created. Now, when the
  63. Makefile compiles your MUD, it will know that you have installed a new module
  64. called mail, and it will go into the directory and compile all the files
  65. within it. Well, almost. What actually happens is the Makefile goes into the
  66. module directory and looks for <i>another</i> makefile that lists all the
  67. source files that need to be compiled for that module, along with all the
  68. libraries and compiler flags that are required for the new code to work.
  69. Make a new makefile in the module directory to let the main Makefile know which
  70. source files will be needed. In your module directory, create a file called
  71. <i>module.mk</i> and edit it. We will only be working with one source file in
  72. this directory, and it will be called <i>mail.c</i>. To let the main makefile
  73. know that this source file will be made, add the following lines of code to your
  74. <i>module.mk</i> file:
  75. <pre class="code">
  76. # include all of the source files contained in this module
  77. SRC += mail/mail.c
  78. </pre>
  79. In general, the path relative to the main src driectory for all source files
  80. in your module should be added to the SRC variable.
  81. <p></p>
  82. Now that your MUD knows that your module exists, you will have to take some
  83. steps to initialize all of the new features your module will add to the MUD.
  84. This is traditionally done by adding an init_xxx() function to your module, and
  85. calling it when the MUD first boots up. Create an init function and fill it with
  86. a nonsense message until we actually have code to initialize. In your new module
  87. directory, create and edit a file called <i>mail.c</i>. To it, add the following
  88. bit of code:
  89. <pre class="code">
  90. // include all the header files we will need from the MUD core
  91. #include "../mud.h"
  92. #include "../utils.h" // for get_time()
  93. #include "../character.h" // for handling characters sending mail
  94. #include "../save.h" // for player_exists()
  95. #include "../object.h" // for creating mail objects
  96. #include "../handler.h" // for giving mail to characters
  97. // include headers from other modules that we require
  98. #include "../editor/editor.h" // for access to sockets' notepads
  99. // include the headers for this module
  100. #include "mail.h"
  101. // boot up the mail module
  102. void init_mail(void) {
  103. log_string("Nothing in the mail module yet!");
  104. }
  105. </pre>
  106. You will notice that we include a header called <i>mail.h</i>, which has not yet
  107. been created. Let's create the header and add all of the functions that source
  108. code outside of the mail module should have access to. In your new module
  109. directory, create and edit a file called {\it mail.h}. To it, add the following
  110. bit of code:
  111. <pre class="code">
  112. #ifndef MAIL_H
  113. #define MAIL_H
  114. // this function should be called when the MUD first boots up.
  115. // calling it will initialize the mail module for use.
  116. void init_mail(void);
  117. #endif // MAIL_H
  118. </pre>
  119. Then, call the init function where all the other modules' init functions are
  120. called. This is a two-step process. First notify the rest of the MUD of this
  121. module's existence by adding a define for it in <i>mud.h</i>. Edit <i>mud.h</i>
  122. in the main src directory. Near the very start of the file, you will see lists
  123. of defined of the form MODULE_XXX. With the rest of your optional modules, add
  124. the line:
  125. <pre class="code">
  126. #define MODULE_MAIL
  127. </pre>
  128. Then go into <i>gameloop.c</i> and call the init function. At the end of the
  129. header files, you will see headers for optional modules. dd anothe entry for
  130. your mail module:
  131. <pre class="code">
  132. #ifdef MODULE_MAIL
  133. #include "mail/mail.h"
  134. #endif
  135. </pre>
  136. Now, go down furhter to where all of the modules are initialized. This will be
  137. in the main() function, right before the gameworld is created. Add your init
  138. function to the lsit of other init functions:
  139. <pre class="code">
  140. #ifdef MODULE_MAIL
  141. log_string("Initializing mail system.");
  142. init_mail();
  143. #endif
  144. </pre>
  145. Notice how both the include for our mail.h header, and the call to our init
  146. function for the mail module are wrapped around #ifdef and #endif statements.
  147. This is to easily allow for the mail module to be turned off. All that needs to
  148. be done is go into mud.h and comment out the line #define MODULE_MAIL. For all
  149. intents and purposes within the code, the mail module no longer exists when
  150. this line is commented out. We have now completed all of the prep work needed
  151. before we can start writing the mail module.
  152. </pre>
  153. </div>
  154. <!-- content ends here-->
  155. </div></div></div>
  156. <!-- navigation starts here -->
  157. <div class="nav-wrap"><div class="nav">
  158. <iframe src="nav.html" height="100%" width="100%" scrolling=no frameborder=0>
  159. </iframe>
  160. <!-- navigation ends here -->
  161. </div></div>
  162. <!--div class="footer">Edit Date: Nov 15, 2008. By Geoff Hollis</div-->
  163. </body>
  164. </html>