Name: | Ostrich Riders |
---|---|
Version: | 0.6.2 |
Author: | Seby and Suiland and Dennis Payne |
License: | GPLv3 |
Operating System: | Unix and Windows |
Website: | http://identicalsoftware.com/ostrichriders/ |
Another Distribution
After releasing Ostrich Riders 0.6.2, I learned it did not compile on Mint 17.3. The error being "‘printf’ was not declared in this scope." The user passed this error by including stdio.h but then hit undefined references to sfml functions. The first error is probably due to different versions of libraries. Some include file under Fedora included stdio.h but not under Mint.
The undefined references was due to the makefile generated from the Code::Blocks project file. Linkers used to require all libraries be at the end of the link command. If you added a library before an object file that needed the library, you would get undefined references. The generated makefile put the -l argument at the start of the link line. Apparently the linker under Fedora no longer has that restriction but Mint must have an older version.
Fonts
Virtualization has been a great help for testing. Instead of simply telling the user how to fix the problem, I installed Mint 17.3 in a virtual machine. This allowed me to solve the next problem before the user found it. To replace the removed sf::Font::GetDefaultFont(), I hard-coded the path to the font. The font is in a different location under Mint.
Distributions typically don't want applications including their own fonts. It wastes disk space, harder to keep up to date, and may not be available to other applications which might want to use the font. I asked on FreeGameDev forums hopping to find the best practice of open source developers. The best practice was unfortunately to ignore the problem.
During my initial investigation, I found the xml file /etc/font/font.conf which contained the directories used to store fonts. It is used by the fontconfig library to find fonts. The command line utility fc-match could easily be made to output the location of the font:
fc-match LiberationSans-Regular.ttf -f "%{file}"
While parsing the xml and searching for the font is possible, it requires that I keep track of changes to xml format. Executing fc-match is also an option but not very elegant. It requires the fontconfig library but conceals that relationship by executing the utility program.
The documentation for fontconfig made using it a little difficult but I managed to mimic the behavior of fc-match. Hopefully FindDefaultFont() can be used to advance the state of the art for open source programs instead of duplicating fonts.
One possible hindrance of using fontconfig is that it will return a font to satisfy your request. If you want a font that isn't installed, it will return a different font. You could bailout if the file name does not match your expectations. I don't believe that is a good solution. In most cases, the font style is not going to make or break your game. A user would much rather see the game running in a different font than failing to run at all. If a user is seeing graphical glitches due to the sizing of the font by all means recommend installing the appropriate font.
Path Not Taken
Even after fixing the compile problem and hard-coded font, the program proved difficult to run. I mentioned in my previous article that the default path for game data is now /usr/share/ostrichriders under Linux. To prevent anyone from being frustrated while testing it before installing, the project file was modified to add an argument when running the program so that it used the data subdirectory.
That might have worked with my original plan of not including a makefile. Since the makefile was included, I should have anticipated that someone would run into problems and documented how to run the program without installing it. Stephen Sweeney suggested loading from the relative path first and falling back to the install location second.
His suggestion is reasonable and caused me to reconsider simply documenting the command line argument to run without installing. What I don't like about the solution is the unpredictability. Every file I load from a relative path means the program behaves differently depending on where it is run. Ostrich Riders now uses the installed location by default. If that is not found, it will try the relative directory. For developers, who might have it installed but also working on changes, a command line argument can specify where to look for the data files.
Stephen's suggestion is helpful for modding a game as you can replace individual files. However, I think you are better off solving that with one base location for files and a single location for user files instead of relative paths. Bt Builder uses physfs to combine the base data files with user files in a directory specifically for Bt Builder. No matter what directory, you run Bt Builder from it behaves in a consistent fashion but still allows overriding individual files.
Static Analysis
Svyatoslav Razmyslov posted about a static analysis of Serious Sam's source code. It was an interesting read but required a closed source program under windows. The open source ccpcheck was suggested as an alternative. Others suggested that static analyzers are not very good and that compilers are detecting more and more problems with source code when all warnings are turned on.
The only warnings that Ostrich Riders generates were for my additions to rotate life and scoring for players. It claims that the current member variable of LifeEntity and RotatingTextEntity. The variable is initialized in the constructor. If there is a way for it not to be initialized, I don't see it. This is the biggest obstacle with warnings. Warnings that are incorrect with no readily apparent change to remove the warning.
Static analysis with cppcheck faired a little better with Ostrich Riders. It claimed that GameScores::addScore would access an array out of bounds. The analysis is correct but also wrong. If you called addScore with a score that is lower than all the current top scores, it would access the array out of bounds. However, that function is only called when the score is greater than the lowest score. Fixing this code is still a good idea just in case a later modification does not ensure that to be the case.
The analysis did alert me to a bug indirectly. While investigating the calls to addScore, I found the code only handled two players. With a little update the third player had his chance in the limelight.
Comments
No comments yet.