KGoldrunner

KGoldrunner - Technical Details

HOME | Previous Installation


This section is aimed at programmers who wish to work on KGoldrunner as a developer or port it to other operating systems and desktops. Before starting, please contact the authors, to make sure you have the latest versions of the distribution files (email addresses are in the "Help, About KGoldrunner" menu option message). Also, have a look at the Installation section of this document.

Compiling and Building KGoldrunner as a Developer

The Installation section describes how to install KGoldrunner into the KDE system directories. To install it into your own area, proceed similarly, but log in as yourself, use one of your own working directories and omit the "make install" command.

If you are familiar with the KDevelop IDE (Integrated Development Environment), there is a "kgoldrunner.kdevprj" project definition file in the "kgoldrunner-V-kdeN" directory (where V is the KGoldrunner version and N is 1 or 2).

Accessing the Documentation and Games Data Files

You will find the English documentation files in "kgoldrunner-V-kdeN/kgoldrunner/docs/en" and the games data files in "kgoldrunner-V-kdeN/kgoldrunner/system".

Among the games data files is one called "levels.tar". If you need to add to the released levels, use the command "tar xf levels.tar" to unpack the levels files into sub-directory "levels". Repack them using the command "tar cf levels.tar levels". The text-file "games.dat" will also need to be edited or replaced. It contains a summary of the files in the "levels" directory (prefixes and counts) and it must be consistent.

When you run KGoldrunner, you will normally access the levels files and documentation installed in the KDE system. For most purposes it will be enough to keep new games and levels in the User area KGoldrunner already provides, while you are editing and testing them. The relevant files are saved in your home directory structure in ".kde/share/apps/kgoldrun" in KDE 1 or ".kde2/share/apps/kgoldrun/user" in KDE 2. If you are changing the documentation, you can access your development version from KGoldrunner by typing in the full path the first time, then saving it as a bookmark.

If you have to access the copies of System games data and levels in your development area, you will need to mimic the KDE "share/apps" directory structure somewhere in your directory area. Either copy or preferably link the games and levels sub-directories into that structure at the correct point. Now, in KDE 1, you execute KGoldrunner with KDEDIR temporarily defined to your structure's base, e.g.:

        KDEDIR=$HOME/mydir ./kgoldrunner

In KDE 2, there is no KDEDIR, but there is a "path" variable KDEDIRS for finding application data files. Set it by using:

        export KDEDIRS=$HOME/mydir:$KDEDIRS

then you can simply use "./kgoldrunner" to execute.

Keeping Versions in Sync

Please note that there is really only one set of source files, graphics files, games files, levels files and documentation for KGoldrunner, even though it is distributed as two sets, one for KDE 1 and one for KDE 2. Only the "make", "configuration" and "project" files are different. So if you change anything, please make certain that it is changed in both distributions.

Also, only the KDE 2 version contains the CVS (Concurrent Version control) repositories and you should "commit" all your changes to them when you finish your work.

Makefiles, KDevelop, "automake" and "autoconf"

When you install KGoldrunner, each directory in the uncompressed distribution files has "Makefile"s which contain specifications for compiling, building and installing the software and files, but these "Makefile"s have been generated by the "./configure" script and are tailored to fit your system. Therefore you should not edit and re-distribute the "Makefile"s, even if you know how!

The best approach is to use KDevelop, which generates all the right files for each directory in your project and allows you to "register" new files for compilation, distribution or installation, whereupon references to them get incorporated into the generated files. The files generated by KDevelop are "Makefile.am", "Makefile.in" and "Makefile" in each project directory and "configure.in", "acinclude.m4", "aclocal.m4" and "configure" in the top directory. All of these, except for "Makefile", are distributed.

The base files are "Makefile.am" and "configure.in". If you want to add to the rules KDevelop generates automatically, these are the files you need to change, but avoid the sections between comments that KDevelop overwrites.

The released "Makefile.am" files contain a few such changes, e.g. to implement "make init", to unpack the levels after "levels.tar" has been installed and to uninstall the levels files and "kgoldrun" directories.

KDevelop uses "automake" to generate "Makefile.in" files from "Makefile.am" and "autoconf" to generate the "configure" script from "config.in", then it uses the "configure" script to generate "Makefile" from "Makefile.in". If you wish, you can do these steps yourself, provided you start by changing only "Makefile.am" and "config.in".

Where to Find KDevelop, "automake" and "autoconf"

KDevelop, "automake" and "autoconf" are (or should be) packages in your Linux distribution. When you install the KDevelop package, "automake" and "autoconf" are installed automatically (or should be). Once installed, KDevelop has extensive and readable built-in documentation.

When "automake" and "autoconf" are installed, the documentation can be found in the "info" documentation browser, which also has a very good writeup on "Make" (a "must read", if you are going to make much sense of the "automake" and "autoconf" documents). Also in "info", see "Standards" (section "Managing Releases", sub-sections "Configuration" and "Makefile Conventions") for further background information.

Portability Concerns

In KDE 1, KGoldrunner is heavily dependent on KDE object and GUI libraries and so is not portable.

In KDE 2, there is just one procedure, "getDirectories", that depends on KDE. It locates the directories where the documentation, games and levels are stored. Everything else depends only on Qt 2 and C++ and so should be portable to other operating systems.

To assist portability further, most file names have been kept down to 8 characters (alphanumeric and underscore only) and file extensions have been kept down to 3 characters (e.g. ".htm" for documentation, rather than ".html").

Compilation Concerns

When changing from KDE 1 to KDE 2, the KDE libraries introduced source-code incompatibilities and so did the Qt library when going from Qt 1 to Qt 2. This meant that the definitions of some classes changed and source code depending on those classes had to change too. KGoldrunner v1.0 has source code that can be compiled either with KDE 1 and Qt 1 or with KDE 2 and Qt 2. Dual compilation depends on three approaches:
  • Defining (or not defining) the pre-processor variable "QT1" (in the KDE 1 version "QT1" is defined in the "Makefile.am" and ultimately in the "Makefile"),
  • Defining some compile-time macros, "myStr", "myChar" and "endData", that smooth out the differences between Qt 1 and Qt 2 classes when handling strings, characters and end-of-file conditions,
  • Using the comments "// QT1_ONLY" and "// QT2PLUS_ONLY" to flag lines that cannot be handled by the first two methods and so have to be modified by "make init".
Regarding the last point, the Qt pre-processor (the MOC compiler) cannot handle C++ pre-processor directives (such as "#ifdef QT1", "#else" and "#endif"). Left to itself, it will process both the Qt 1 and Qt 2 versions of certain lines and cause compile-time errors. So in KDE 1 the script "fix_src" adds a comment (//) to lines containing the "QT2PLUS_ONLY" string and removes it from lines containing the "QT1_ONLY" string. It does the opposite in KDE 2. If the source files have already been changed, "fix_src" has no effect, so you can run it anytime without worrying about whether it has been run before.

The script requires a string parameter that ends in "kde1" or "kde2". In the "make init" rule, which runs "fix_src", this parameter is supplied by the Makefile's VERSION variable, as set up in the KDevelop project definition (e.g. "1.0-kde1" or "1.0-kde2").

Danger: Software Interrupts

KGoldrunner is controlled by outside events, such as timer events, mouse clicks, keystrokes and window management actions. Any of these can happen at any moment, depending on the whims of the user and the demands of the animation. Qt also has a very handy "signal and slot" mechanism, which is used extensively in KGoldrunner.

Ordinarily, Qt will not execute event-handling procedures and slots until you return from the current procedure and Qt resumes control (i.e. events are queued). There are however some cases where an event-handler or slot can be executed unexpectedly, between two lines of source code. If it changes data items or objects you are currently accessing, some very weird and hard-to-find bugs can result, ranging from the hero running amok to a full-on "Segmentation Fault" crash. The following are cases where this kind of thing can happen:

  • When you "emit" a signal or invoke a procedure that has been defined as a signal, all procedures that have been linked to it by a "connect" will be executed before the next line of source code. It is easy to forget that when programming.

    For example, the signal "caughtHero()" is connected to slot "herosDead()", which radically changes the state of the game, so "emit caughtHero();" is always followed by a "return".

  • In some places KGoldrunner invokes "qApp->processEvents()", which causes all queued events to occur immediately, including any waiting timer or mouse events. Usually the idea is to get "QMainWindow", etc. to re-organize the main window correctly (e.g. when going in and out of Edit mode). The boolean flag called "loading" causes user actions to be ignored while the window is being re-constructed or a level is being loaded.

  • There seem to be some rare cases where a Qt library procedure will emit a signal and cause one of your slots to execute unexpectedly. For example, inserting the first line of text in a list box (class QListBox), can cause a "highlighted" signal.

The Main Modules of KGoldrunner

  • main simply sets up the KGoldrunner window, sets the font and starts the application event loop. This also seems to be the place to initialise language translation in later versions.
  • kgoldrunner is the user interface. It implements all menus, buttons and dialog boxes, referees play, keeps score and loads or reloads levels. It also keeps track of high scores, saves games, loads games, implements the game editor and contains the Qt 2 help browser.
  • kgoldrunnerwidget provides the playing area in which levels and animation are drawn. It also handles mouse events and paints or repaints the playing area's frame and title.
  • kgrobj contains the classes and methods that implement game play.

    The class KGrObj and its descendants display the various objects in the game and im[plement their behaviour (e.g. bricks, ladders, gold, hidden ladders, etc.).

    The class KGrFigure and its descendants KGrHero and KGrEnemy display the hero and enemies and implement all their movement and the rules controlling that movement. Timer events implement animation and the key methods are "startWalk", "walkTimeDone", "initFall" and "fallTimeDone". Enemies also have "captiveTimeDone" and their search strategy is implemented by "searchbestway".

The "games.dat" File Format

The "games.dat" files are stored in the KGoldrunner System and User data area, as documented in the Installation section and above. The file in the System area lists System games and the file in the User area (if any) lists games belonging to the logged in user.

Each game in each file is represented by one line or two lines of text.

The second line is optional and contains a description of the game, that is displayed by clicking the "More" button in the Level Selection Dialog box. The text is automatically word-wrapped when it is displayed. Paragraph breaks are represented by the characters "\n\n" (i.e. the "newline" characters as represented in C and C++).

The first (maybe the only) line contains four fields, separated by a space, as follows:

  1. The number of levels in the game,
  2. The rules the game uses (K = KGoldrunner and T = Traditional),
  3. The filename prefix for the game (1-5 lower case alphabetic characters),
  4. The name of the game (on the rest of line: can include spaces).

The "levels" File Format

Levels files are all stored in the "levels" sub-directory in the KGoldrunner System or User data area, as documented in the Installation section and above. They all have names of the form "prefixNNN.grl", where "prefix" is the game's filename prefix (e.g. "tute" or "plws") and NNN is a 3-digit level number (e.g. "tute008.grl" is level 8 of the Tutorial game). Level numbers should always start at 001 and be consecutive, up to the number of levels in the game. If they are not, KGoldrunner will issue a warning message.

An exception is the special file "level000.grl", which must be present in the System levels sub-directory. It contains the "ENDE" screen, which appears when the game is over ("ENDE" is German for "END").

Each level file is a text-file, containing one or more lines as follows:

  1. This line contains exactly 560 characters, representing the 20 rows of 28 objects in the level's starting position. The codings are defined in "kgrobj.h" and are documented under "Keyboard Short-Cuts" at the end of the Game Editor section.
  2. (optional) The name of the level appears here. The line is empty if there is a hint but no name.
  3. (optional) The hint for the level appears on this and subsequent lines. The text is automatically word-wrapped when it is displayed, so each paragraph should be on one line only, with a blank line between paragraphs. The display widget has a scrollbar and can handle any amount of text.

The High-Score File Format

Released high-score files for the System games are stored in the System data area, but are "read-only". The System file for high scores in a game is copied to the User data area and the user's high score is added, whenever the user first achieves a high score for that game. After that, all high scores achieved are added to the User copy of the high-score file. High-score file names are of the form "hi_prefix.dat", where "prefix" is the game's filename prefix (e.g. "tute" or "plws").

The file is recorded in the portable binary data format implemented by the Qt library's QDataStream class. There are up to 10 records, in descending order of score achieved, and each record contains four fields as follows:

  1. The user's name (string),
  2. The level achieved (16-bit integer),
  3. The score achieved (32-bit integer),
  4. The date and time when the score was achieved (string).

The Saved-Game File Format

The saved game file is stored in the User data area and its name is "savegame.dat". It is a text file, with one line per save, and up to 30 game positions can be saved. The most recent save is first and the oldest is last. Each line contains seven formatted columns as follows:
  1. The filename prefix of the game saved,
  2. The level reached,
  3. The number of lives left,
  4. The score,
  5. The day of the week,
  6. The date, in YYYY-MM-DD format,
  7. The time, in HH:MM format.
When this file is displayed, with column headings, the filename prefix is used to look up the name of each game in the games list (as loaded from "games.dat" when KGoldrunner starts).


HOME | Previous Installation