Name: | Achemy Quest / Open Alchemist |
---|---|
Version: | 0.4 |
Author: | Guillaume Delhumeau, Dennis Payne, Antoine Morineau, strato and usr_share |
License: | GPLv2 |
Operating System: | Unix and Windows |
I had never heard of Open Alchemist when I was approached to join a project to make modifications to it. The game itself wasn't something I would normally play. The closest game I had played for any significant time was Puzzle Quest. Self imposed deadlines for other project would be negatively impacted. However a good two player puzzle game would be a great addition to the arcade machine.
What is ClanLib?
Open Alchemist used the ClanLib library for graphics and input. I had heard of the library but had never looked into it. The team wanted to use SFML or SDL2 to make the program more portable. Converting to a different library typically meant you were spending time reimplementing functionality. I tried to search for more information on the library.
ClanLib 2.3 was included with Fedora. Open Alchemist and Super Methane Brothers used the library. Debian and derivatives included ClanLib 1.0 for the program Trophy. The website for the library was gone. I eventually found the github repository. The most recent version in github was 4.0. Why was no one shipping newer versions? Each version of the library changed the API. If Fedora shipped 4.0, they either would still need to have 2.3 as well or would have to update the two games to the newest version of the library.
Given the state of ClanLib switching to different library seemed wise. First we needed to understand what they used from ClanLib. It setup the display window, keyboard/mouse input, played sound and music, loaded images, handled sprite animation, read zip files, and parsed XML. SDL2 handled the display window and input but needed additional libraries like SDL2_mixer and SDL2_image to handle playing music and load images. For reading zip files, I've used physfs. Which just left sprite animation and parsing XML.
Replacing ClanLib
My preference for a change such as this was to do it incrementally. Unfortunately ClanLib's API was tied together tightly and didn't allow a slow replacement with the exception of music and sound. The first step in that case was to compile everything without ClanLib. There was no check in for these intermediary steps but it involved commenting out all ClanLib classes and functions. After that initial step I started adding back functionality.
The sprite class features used by Open Alchemist weren't very extensive. Essentially you were loading a couple of images, tracking state and displaying the correct image. I wrote a simple class to mimic the used functions of the ClanLib. It became clear that implementing a wrapper for the image and font classes would also be needed. Only the subset of functionality used by Open Alchemist was coded.
For XML parsing in the past, I've used expat. It was a good library but it didn't construct a document object model. To implement the functionality of ClanLib, a DOM XML parser seemed like a better choice. However our goal included a Windows release. None of the DOM XML libraries on Fedora included cross-compiler support. As with the sprite class, I wrote a simple class to mimic the resource manager which loaded the XML files in ClanLib.
The initial implementation did lose some functionality. Despite the new sprite class, animation was not supported. It was added back shortly after the first conversion was committed. Sound and music took a little longer to be restored. Overall replacing ClanLib took less time than I expected.
Text vs. Image
The code base of Open Alchemist was constructed well. The game had a stack of states. When in the game and you pressed the pause button, the pause state would be pushed on the stack. The pause state had multiple MenuItem derived classes which would draw the appropriate choices on the screen. The MenuItem classes were hard-coded but the graphics that appeared were specified in an XML file.
One decision that did not sit well with me was the use of images. ClanLib had fonts which were an image and you specified what characters are in the image. For Open Alchemist they used this only for score and number of combos the player did. All other text used in the game were stored in images. This meant that supporting multiple languages would not be easy to implement.
The pause state used the BasicItem class for all of it's choices. The BasicItem loaded a selected and unselected image defined in the XML file along with an optional unavailable image. I could have extended the class to support specifying the text but it seemed better to have a separate class to handle text options. The BasicTextItem functioned like the BasicItem but took text from the XML file and displayed it in different colors for selected, unselected and unavailable. The load_basic_menu_item function of MenuState would look at the XML and construct either a BasicItem or a BasicTextItem depending on what was specified.
After the implementing the text version of BasicItem class, I created a text version of MultipleChoicesItem used on the option screen. The options menu still allowed you to specify the renderer even though it was no longer used. This was followed by DualChoiceItem for the quit and game over screens. These were built in the same fashion.
In an ideal world, the options and pause state would be the same state object with different XML configuration. This was a problem with other graphical elements as well. Our modification was to have a smaller screen. Certain features such as displaying the current high score or the unlocked elements could not be removed. Moving them outside the visible display worked but disabling them would be cleaner.
Beyond Open Alchemist
While Alchemy Quest was envisioned as a demake of Open Alchemist, we wanted to go beyond the original. I have started adding support for two players but more work will be needed. Many more potential features have been discussed. A design document was made and changes continue to be incorported.
Comments
No comments yet.