packages.txt 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. -----------------------------
  2. MANAPLUS PACKAGE SYSTEM
  3. -----------------------------
  4. 1. INTRODUCTION
  5. 2. LOCATION OF DATA
  6. 3. CONTENTS OF DATA PACKAGE
  7. 4. TYPES OF DATA
  8. 5. INITIALIZING PACKAGE MANAGEMENT
  9. 6. LOADING A REQUESTED RESOURCE
  10. 7. RESOURCE MANAGEMENT DETAILS
  11. 1. INTRODUCTION
  12. Mana is expected to grow continuously with updates to the game world
  13. occurring relatively frequently. More often so than for example new releases
  14. of the game client. To make sure players don't have to update their data
  15. manually all the time, by for example downloading the latest from the website,
  16. the Mana client should be able to automatically obtain new data packages from
  17. the server.
  18. Note: To reduce the load on the server (which isn't expected to have huge
  19. free uploading resources), the idea is that the server will only send a
  20. torrent file to the client and that the file is subsequently downloaded from
  21. several locations that have volunteered to spread Mana data files. Ultimately
  22. a simple option on the client will even allow players to contribute their
  23. excess bandwidth to help other players get the updates faster.
  24. 2. LOCATION OF DATA
  25. There are two locations where Mana can look for game data. The install data
  26. directory and the data directory in the user's home directory. The latter one
  27. doesn't have to be used for Windows users, but is required for dynamic updates
  28. for UNIX users, who generally won't have write permissions to the install
  29. data directory. So for UNIX the two locations are:
  30. /usr/local/share/manaworld/data/*
  31. ~/.manaworld/data/*
  32. While for Windows all the data will be located at:
  33. C:\Program Files\Mana\data\*
  34. In the UNIX case it doesn't matter in which order the data directories are
  35. examined.
  36. 3. CONTENTS OF DATA PACKAGE
  37. The contents of the data packages are strictly categorized and all packages
  38. share a single root, similar to the paths on a UNIX system. The name of the
  39. package is irrelevant. An example of the contents is given by:
  40. /graphics/sprites/forest/pinetree.png
  41. /graphics/sprites/furniture/bed.png
  42. /graphics/tiles/dark_forest.png
  43. /graphics/tiles/city.png
  44. /music/eagles_are_watching.xm
  45. /music/silent_rose.xm
  46. /sound/battle/sword1.ogg
  47. /sound/battle/sword2.ogg
  48. /maps/deep_desert.tmx
  49. /maps/desert_town.tmx
  50. /tilesets/dark_forest.tsx
  51. /tilesets/city.tsx
  52. /scripts/Portal.rb
  53. /scripts/PawnShop.rb
  54. /scripts/Fountain.rb
  55. 4. TYPES OF DATA
  56. png - The preferred format for images
  57. xm - The preferred format for music (or other kinds of module formats)
  58. ogg - The preferred format for sound effects
  59. tmx - The map format (to be implemented)
  60. tsx - The tile set format (to be implemented)
  61. rb - A Ruby script file (application to be discussed)
  62. 5. INITIALIZING PACKAGE MANAGEMENT
  63. When Mana starts it will scan its data directories for both packages (archives)
  64. and directories. When a directory is found with the same name as a package, the
  65. directory is the preferred location to load data from as it is assumed to be
  66. more up to date.
  67. Each package will have an ID and a file listing associated with it. Having made
  68. a list of all packages they are processed in the order of their IDs. A mapping
  69. is made from file to package, as follows:
  70. /music/eagles_are_watching.xm -> /usr/local/share/manaworld/data/musicpack
  71. /music/silent_rose.xm -> /usr/local/share/manaworld/data/musicpack
  72. /sound/battle/sword1.ogg -> ~/.manaworld/data/patch1
  73. /sound/battle/sword2.ogg -> ~/.manaworld/data/patch1
  74. ...
  75. Because the packages are loaded in the order of their IDs, it is made sure that
  76. each file will always point to the package in which is was last updated. The
  77. package IDs make sure that there is an absolute ordering of the packages.
  78. To allow the client to get rid of old packages, a package can declare an
  79. arbitrary amount of packages with a lower ID than itself as obsolete. These
  80. packages will then be ignored by the client, and optionally they can be
  81. automatically deleted.
  82. 6. LOADING A REQUESTED RESOURCE
  83. When the game starts and during the game, resources will continuously be asked
  84. for. A resource manager will take care that each resource is only loaded once.
  85. It also makes sure that the resources are loaded from the right package using
  86. the constructed mapping.
  87. As noted above, the resource manager makes sure directories are preferred
  88. to package files when resources are loaded. The presence of directories is
  89. only expected in the case of developers that will relatively frequently update
  90. the data while working on the next package to be released.
  91. 7. RESOURCE MANAGEMENT DETAILS
  92. The resource management technique is critical to the overall success of the
  93. package management system as a whole. Resources are loaded at runtime as they
  94. are needed, and unloaded as they become unused. In order to ensure the
  95. autonomous functioning of this process reference counting is the agreed upon
  96. technique for managing loaded resources in Mana.
  97. For those unfamiliar with the practice of reference counting, it involves
  98. every resource object having a variable containing the number of references to
  99. the object. When a reference is added the function addRef() is called and when
  100. it is removed the function release() is called. When the reference count
  101. reaches zero the object will automatically delete itself, thus handling the
  102. cleanup of resources.
  103. Reference counting will form the core of the resource management system. Each
  104. resource object will have the functionality of a reference counted object. The
  105. resource manager will hold ResourceEntry objects. The resource entry object
  106. contains a pointer to the resource as well as the location of the path of the
  107. file the resource was loaded from. This would look something like:
  108. /**
  109. * A generic reference counted resource object.
  110. */
  111. class Resource {
  112. public:
  113. /**
  114. * Loads the resource from the specified path.
  115. * @param filePath The path to the file to be loaded.
  116. * @return <code>true</code> if loaded <code>false</code> otherwise.
  117. */
  118. virtual bool Load(std::string filePath) = 0;
  119. ...
  120. /**
  121. * Increments the reference counted of this object.
  122. */
  123. void addRef() { ++referenceCount; }
  124. /**
  125. * Decrements the reference count and deletes the object
  126. * if no references are left.
  127. * @return <code>true</code> if the object was deleted
  128. * <code>false</code> otherwise.
  129. */
  130. void release() {
  131. --referenceCount;
  132. if (!referenceCount)
  133. {
  134. delete this;
  135. return true;
  136. }
  137. return false;
  138. }
  139. private:
  140. unsigned int referenceCount;
  141. };
  142. ...
  143. /**
  144. * A resource entry descriptor.
  145. */
  146. struct ResourceEntry {
  147. Resource* resource;
  148. std::string filePath;
  149. };
  150. ...
  151. The resource manager would then hold a mapping containing the resource entry as
  152. well as the string defining its resource identification path. The resource
  153. manager would thus look something like this:
  154. /**
  155. * A class for loading and managing resources.
  156. */
  157. class ResourceManager {
  158. public:
  159. ...
  160. private:
  161. std::map<std::string, ResourceEntry> resources;
  162. };
  163. ...
  164. This will allow the game to load resources with little awareness of the actual
  165. path from which they were loaded. The resource manager will also act as a
  166. resource object factory. A factory object is an object that creates an
  167. instance of an object derived from a common base class. In this case it will
  168. create Resource objects. This would make the ResourceManager object look like
  169. this:
  170. /**
  171. * A class for loading and managing resources.
  172. */
  173. class ResourceManager {
  174. public:
  175. enum E_RESOURCE_TYPE
  176. {
  177. MAP,
  178. MUSIC,
  179. IMAGE,
  180. SCRIPT,
  181. TILESET,
  182. SOUND_EFFECT
  183. };
  184. /**
  185. * Creates a resource and adds it to the resource map.
  186. * The idPath is converted into the appropriate path
  187. * for the current operating system and the resource
  188. * is loaded.
  189. * @param type The type of resource to load.
  190. * @param idPath The resource identifier path.
  191. * @return A valid resource or <code>NULL</code> if
  192. * the resource could not be loaded.
  193. */
  194. Resource* Create(const E_RESOURCE_TYPE& type,
  195. std::string idPath);
  196. ...
  197. private:
  198. std::map<std::string, ResourceEntry> resources;
  199. };
  200. ...
  201. Loading a resource would then look something like:
  202. Image* img = (Image*) ResourceManager.Create(ResourceManager::IMAGE,
  203. "/graphics/tiles/dark_forest.png");