This document is under active development and discussion!

If you find errors or omissions in this document, please don’t hesitate to submit an issue or open a pull request with a fix. We also encourage you to ask questions and discuss any aspects of the project on IRC. New contributors are always welcome!

Getting Started

Flexible Isometric Free Engine (FIFE) is a multi-platform isometric game engine written in C. It comes with Python bindings allowing users to create games using Python as well as C. The engine is extendable and enables you to add any feature you can imagine to your project. It’s a very flexible game creation framework and not tied to any genre, but geared towards an RTS or RPG using an isometric or top-down view style.

The developer manual offers programmers documentation and examples useful in working with fifengine.

What’s in the Manual

This manual will cover all aspects of custom development with fifengine:

  • the compilation of fife

  • the engine

  • the Programming Style Guide explains the programming style and coding standards used

1. Compiling Fifengine

Compiling Fifengine is a complicated and time consuming task. This chapter explains how to setup a compilation environment for Fife.

You’ll find detailed setup steps for fifengine on the operating systems Linux, Windows and Mac.

The individual subchapters have the same structure:

Firstly, we’ll setup an IDE, then the compiler toolchain and additionally needed build-tools.

Secondly, we’ll discuss how to get all the dependencies, either by building them from source or by using pre-build binaries.

Thirdly, we’ll show how to build fifengine itself.

Without further ado, let’s get started.

1.1. Building Fifengine on Linux

This guide will help you build fife on various flavors of linux.

1.1.1. Build Environment

Firstly, we need to setup an IDE and several build tools.

1.1.1.1. IDE

The are several good IDEs available, including:

Now, that you have an IDE installed, you need to setup the required build tools. This includes an compiler of your choice, the build system CMake, the interface generator Swig and Python.

1.1.1.2. Compiler

You can compile fife with gcc or clang.

We don’t ship a C/C compiler in our Windows SDK. Instructions on how to set up a compiler and build system for C development on Windows can be found [here](https://userbase.kde.org/KDevelop4/Manual/WindowsSetup).
1.1.1.3. CMake

Fife uses CMake as build system. The build system generates the build configuration for the project and set the project up for your specific IDE.

1.1.1.4. SWIG

Fife uses Swig as interface generator. Fife itself is written in C++, for being able to access the API from Python, we are wrapping it using Swig.

1.1.1.5. Python

To build the Python extension you need Python. Fife works with Python 2.7 and Python 3.4+

1.1.2. Dependencies

Fife depends on a multitude of external libraries.

Our next step is to ensure that all dependencies are installed properly, before you try to build fifengine itself. You have the choice of building the dependencies from source or fetching pre-build, packaged binaries.

We do not provide a pre-packaged software development kit for Linux.

Additionally, you find more detailed information in the dependencies chapter.

1.1.2.1. Building dependencies from source
We are working on building the dependencies on the fly. For now we simply use pre-build packages.
1.1.2.2. Using packaged dependencies
Debian based systems

On debian based systems you can grab all dependencies by installing the following packages:

Python 2:

apt-get install -y build-essential libalsa-ocaml-dev libsdl2-dev libboost-dev libsdl2-ttf-dev libsdl2-image-dev libvorbis-dev libalut-dev python2.7 python-dev libboost-regex-dev libboost-filesystem-dev libboost-test-dev swig zlib1g-dev libopenal-dev git python-yaml libxcursor1 libxcursor-dev cmake cmake-data libtinyxml-dev libpng-dev libglew-dev

Python 3:

apt-get install -y build-essential libalsa-ocaml-dev libsdl2-dev libboost-dev libsdl2-ttf-dev libsdl2-image-dev libvorbis-dev libalut-dev python3 python3-dev libboost-regex-dev libboost-filesystem-dev libboost-test-dev swig zlib1g-dev libopenal-dev git python3-yaml libxcursor1 libxcursor-dev cmake cmake-data libtinyxml-dev libpng-dev libglew-dev
Gentoo based systems

Python 2:

emerge --ask --verbose --noreplace libvorbis libogg media-libs/openal boost libsdl2 sdl2-image sdl2-ttf git pyyaml dev-lang/swig dev-libs/tinyxml dev-util/cmake media-libs/glew dev-lang/python2.7

Python 3:

emerge --ask --verbose --noreplace libvorbis libogg media-libs/openal boost libsdl2 sdl2-image sdl2-ttf git pyyaml dev-lang/swig dev-libs/tinyxml dev-util/cmake media-libs/glew dev-lang/python3 dev-python/future
Fedora based systems

Python 2:

dnf install git python2 gcc gcc-c++ SDL2 SDL2-static SDL2-devel SDL2_ttf SDL2_ttf-devel SDL2_image SDL2_image-devel boost boost-devel libvorbis libvorbis-devel libogg libogg-devel openal-soft openal-soft-devel zlib zlib-devel mesa-libGL mesa-libGL-devel mesa-libGLU mesa-libGLU-devel swig libXcursor libXcursor-devel alsa-lib alsa-lib-devel python-alsa PyYAML allegro5 cmake tinyxml-devel libpng libpng-devel fifechan fifechan-devel fifechan-opengl fifechan-opengl-devel fifechan-sdl fifechan-sdl-devel glew glew-devel

Python 3:

dnf install git python3 gcc gcc-c++ SDL2 SDL2-static SDL2-devel SDL2_ttf SDL2_ttf-devel SDL2_image SDL2_image-devel boost boost-devel libvorbis libvorbis-devel libogg libogg-devel openal-soft openal-soft-devel zlib zlib-devel mesa-libGL mesa-libGL-devel mesa-libGLU mesa-libGLU-devel swig libXcursor libXcursor-devel alsa-lib alsa-lib-devel python-alsa python3-PyYAML allegro5 cmake tinyxml-devel libpng libpng-devel fifechan fifechan-devel fifechan-opengl fifechan-opengl-devel fifechan-sdl fifechan-sdl-devel glew glew-devel
Arch Linux based systems

Python 2:

pacman -S sdl2 boost sdl2_ttf sdl2_image libvorbis libogg openal swig python2 zlib libgl libpng tinyxml python2-pillow cmake glew

Python 3:

pacman -S sdl2 boost sdl2_ttf sdl2_image libvorbis libogg openal swig python zlib libgl libpng tinyxml python-pillow python-future cmake glew

NOTE that you will also need to install fifechan from source, until it’s available as a package for your distro. Fifechan is in the following distros: Fedora

1.1.3. Building Fifechan

To build Fife, you’ll of course need the Fifechan source code. You can download a Fifechan source code package or fetch the latest source using git.

git clone https://github.com/fifengine/fifechan.git && cd fifechan
mkdir _build; cd _build; cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr ..

Building with Clang instand of GCC Compiler:

mkdir _build; cd _build; cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ ..
make && sudo make install

1.1.4. Building Fifengine

Finally, we can compile Fifengine.

To build Fife, you’ll of course need the Fife source code. You can download a Fife source code package or fetch the latest source using git.

git clone https://github.com/fifengine/fifengine.git && cd fifengine

If you have only an old version of cmake (2.X) then please do this:

mkdir ../_build; cd ../_build/; cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr ../fifengine/
instand of: mkdir _build; cd _build; cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr ..

To build fife with Python support only do:

With "-DPYTHON_EXECUTABLE=/PATH/TO/PYTHONEXECUTABLE" you can change the Python Version what you want to use. If it is not the System defualt Python Version.
mkdir _build; cd _build; cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr ..

To build it with Python support only do (with Clang instand of GCC Compiler):

mkdir _build; cd _build; cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ ..

To build fife with Python support and with c/c++ lib and header files do:

mkdir _build; cd _build; cmake -Dbuild-library=ON -DCMAKE_INSTALL_PREFIX:PATH=/usr ..

To build fife with Python support and with c/c++ lib and header files do (with Clang instand of GCC Compiler):

mkdir _build; cd _build; cmake -Dbuild-library=ON -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ ..

after that you can build the project using make and then install it:

make && sudo make install

1.2. Building Fifengine on Windows

1.2.1. Build Environment

Firstly, we need to setup an IDE and several build tools.

1.2.1.2. Compiler

You need msvc or gcc or mingw-gcc.

In case you installed MS Visual Studio, then the MSVC compiler is already installed.

gcc and mingw-gcc toolchain support is not ready, yet

In case you want to build using gcc, we suggest using one of the following toolchains:

1.2.1.3. CMake

Fife uses CMake as build system. The build system generates the build configuration for the project and set the project up for your specific IDE.

1.2.1.4. SWIG

Fife uses Swig as interface generator. Fife itself is written in C++, for being able to access the API from Python, we are wrapping it using Swig.

1.2.1.5. Python

To build the Python extension you need Python. Fife works with Python 2.7 and Python 3.4+

1.2.2. Dependencies

Fifengine depends on several external libraries.

This is the detailed list.

Our next step is to ensure that all dependencies are installed properly, before you try to build fifengine itself. You have the choice of building the dependencies from source or fetching pre-build, packaged binaries.

1.2.2.1. Using packaged dependencies

The pre-build binaries are build on-the-fly, when building Fifengine on Appveyor. You find MSVC 14 builds here: https://ci.appveyor.com/project/LinuxDonald/fifengine

We are working on building the dependencies on the fly using the MinGW toolchain.

These builds are also included in our pre-packaged Windows development kit, the Fife-SDK.

The default install location is fifengine-dependencies next to your fifengine source folder. When you’re using an alternative location, please set the library and include dirs for the dependencies accordingly.

1.2.2.2. Building dependencies from source

You can build the dependencies for Windows using MSVC.

The CMake config file for the dependencies is fifengine\dependencies\CMakeLists.txt. It includes the individual scripts for fetching and building dependencies. They are located in the main CMake scripts folder: fifengine\cmake\get-*.cmake.

Let’s configure the dependencies project and then build all dependencies:

cmake dependencies -G "Visual Studio 14" -B../fifengine-dependencies/build
cmake --build ../fifengine-dependencies/build --target ALL_BUILD --config Release

You’ll now find the dependencies the fifengine-dependencies folder:

dir ..\fifengine-dependencies
dir ..\fifengine-dependencies\downloads
dir ..\fifengine-dependencies\includes /s

1.2.3. Building Fifengine

If you have Python 2 and Python 3 installed you can choose the Version with the comamnd:

With "-DPYTHON_EXECUTABLE=/PATH/TO/PYTHONEXECUTABLE" you can change the Python Version what you want to use. If it is not the System defualt Python Version.

Finally, we can compile Fifengine.

1.3. Building Fifengine on Mac

1.3.1. Build Environment

Firstly, we need to setup an IDE and several build tools.

1.3.1.2. Compiler

You can compile fife with clang.

1.3.1.3. CMake

Fife uses CMake as build system. The build system generates the build configuration for the project and set the project up for your specific IDE.

1.3.1.4. SWIG

Fife uses Swig as interface generator. Fife itself is written in C++, for being able to access the API from Python, we are wrapping it using Swig.

1.3.1.5. Python

To build the Python extension you need Python. Fife works with Python 2.7 and Python 3.4+

1.3.2. Dependencies

Fife depends on a multitude of external libraries.

Our next step is to ensure that all dependencies are installed properly. We do this by either compiling and installing them manually or by fetching and installing pre-compiled binaries.

We do not provide a pre-packaged software development kit for Mac.

Additionally, you find more detailed information in the dependencies chapter.

1.3.2.1. Building dependencies from source
We are working on building the dependencies on the fly. For now we simply use pre-build packages.
1.3.2.2. Using packaged dependencies

brew update && brew install swig sdl2 sdl2_image sdl2_ttf freetype openal-soft tinyxml glew libvorbis (for python 3 support: python3)

1.3.3. Building Fifechan

To build Fife, you’ll of course need the Fifechan source code. You can download a Fifechan source code package or fetch the latest source using git.

git clone https://github.com/fifengine/fifechan.git && cd fifechan
mkdir _build; cd _build; cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr ..
make && sudo make install

1.3.4. Building Fifengine

Finally, we can compile Fifengine.

To build Fife, you’ll of course need the Fife source code. You can download a Fife source code package or fetch the latest source using git.

git clone https://github.com/fifengine/fifengine.git && cd fifengine

To build fife with Python support only do:

With "-DPYTHON_EXECUTABLE=/PATH/TO/PYTHONEXECUTABLE" you can change the Python Version what you want to use. If it is not the System defualt Python Version.
mkdir _build; cd _build; cmake ../fifengine

To build fife with Python support and with c/c++ lib and header files do:

mkdir _build; cd _build; cmake -Dbuild-library=ON ../fifengine

after that you can build the project using make and then install it:

make && sudo make install

1.4. CMake

CMake is a "meta build system" that reads a description of the project written in the CMakeLists.txt files and emits a build system for that project of your choice using one of CMake’s "generators".

This allows CMake to support many different platforms and build tools. You can run cmake --help to see the list of supported "generators" on your platform.

1.5. CMake Build Types

Several build types are supported.

  • Release

  • Debug

  • RelWithDebInfo

  • MinSizeRel

For the single configuration generators (e.g. "Unix Makefile" and "Visual Studio 12 2013"") you set the build type when invoking cmake by passing -DCMAKE_BUILD_TYPE=<build_type> where <build_type> is one of the build types specified above.

For multi-configuration generators (e.g. Visual Studio) you don’t set the build type when invoking CMake and instead set the build type within Visual Studio itself (by using the dropdown in the top navigation bar).

1.6. CMake configuration options

There are three groups of configuration options:

  • CMake’s own config options: The CMAKE_* flags allow to declare useful build variables, including locations, environment variables, compiler information and compiler flags. You find more details in the CMake Wiki - Useful Variables.

  • Fifengines’s config options:We provide several configuration flags, which allow configuring the fifengine build. They control which subsystems/components of fifengine to build. You find the overview in the CMakeLists file.

  • Config options for finding dependencies: Finally, we have *_INCLUDEDIR + *_LIBRARY_DIR flags. These are used to set the paths to the headers and lib folder for dependencies.

On the command line options can be passed to cmake using the -D option. In ccmake and cmake-gui these can be set in the user interface.

We are guiding CMake to find the dependencies automatically. The default location for dependencies is a folder fifengine-dependencies next to the fifengine source folder. The FifeSDK installs the dependencies by default into this location.

If the dependencies are placed into a folder of your choice, you need to give the paths to each dependencies to CMake. Either by declaring them on the CLI by using the *_INCLUDEDIR + *_LIBRARY_DIR flags or by using the CMake-Gui and selecting the folders.

cmake ..\fifengine

We are building in a seperate build folder: the fifengine-build folder, project source is one up, then down into fifengine. This is called out-of-source-tree building.

-G %GENERATOR%

You need to specifiy the requested GENERATOR IDE. This is either "Visual Studio 14" or "Mingw makefiles". Others values are possible. See CMake generators for more.

-DCMAKE_PREFIX_PATH="C:\fifesdk\fifengine-dependencies\include"

where the includes are

-DCMAKE_BUILD_TYPE=%CONFIGURATION%

Release or Debug

-DCMAKE_INSTALL_PREFIX="C:\fifesdk\fife-install"

the installation folder, after build

-DBOOST_INCLUDEDIR="C:\fifesdk\fifengine-dependencies\include\boost"

helper to find boost

-DBOOST_LIBRARYDIR="C:\fifesdk\fifengine-dependencies\lib\boost"

helper to find boost

-DPYTHON_INCLUDE_DIR="C:\fifesdk\python\include"

helper to find Python

-DPYTHON_LIBRARY="C:\fifesdk\python\libs\python27.lib"

helper to find Python

-DSWIG_DIR=C:\fifesdk\swig

helper to find Swig folder

-DSWIG_EXECUTABLE=C:\fifesdk\swig\swig.exe

helper to find Swig executable

-DSDL2_INCLUDE_DIR="C:\fifesdk\fifengine-dependencies\include\SDL2"

helper to find SDL2 headers

-DSDL2_LIBRARY_DIR="C:\fifesdk\fifengine-dependencies\lib\x86"

helper to find SDL2 library

-Dbuild-library=ON

This build flags enables building the shared library (ON). When disabled (OFF), then only the Python extension is build.

-DBUILD_SHARED_LIBS=ON

This build flag controls, whether to build a shared (ON) or static library (OFF).

1.7. Running the demos

The demos have their own git repository: https://github.com/fifengine/fifengine-demos

Assuming that you have successfully built fife, you will be able to change directory to one of the fife demos located in <fifengine-demos> and type: python run.py.

You might also run the demos by double-clicking the run.py file in your file browser. This requires python to be associated with .py files in order to work.

2. Engine

2.1. Overview Diagram

Engine Overview
Figure 1. Engine Overview

2.2. Engine Settings

NOTE: This information is Python specific

When a Python program wants to use FIFE engine, it has to provide some basic engine settings to FIFE.

This is done by writing the settings to a xml file and let FIFE know the file name.

FIFE loads the settings from that file.

If no file is given, FIFE searches for the "settings.xml" file in the current directory.

This section describes the different settings that can be set in settings.xml file.

2.2.1. Basic settings

Every program has to give some basic settings.

These are FullScreen, PlaySounds, ScreenResolution, RenderBackend and Lighting.

If any one of them is excluded, FIFE cannot load the program and will generate error:

AttributeError: 'NoneType' object has no attribute 'findChildByName' .

So, the basic xml file to load FIFE by the client looks like this:

<?xml version='1.0' encoding='UTF-8'?>
<Settings>
    <Module name="FIFE">
        <Setting name="FullScreen" type="bool"> False </Setting>
        <Setting name="PlaySounds" type="bool"> True </Setting>
        <Setting name="RenderBackend" type="str"> OpenGL </Setting>
        <Setting name="ScreenResolution" type="str">1024x768</Setting>
        <Setting name="Lighting" type="int"> 0 </Setting>
    </Module>
</Settings>

2.2.2. Additional Settings

Apart from these basic settings, other settings are also possible.

All these settings are given below with a brief description attached to them below:

2.2.2.1. Window Settings
WindowTitle

This is a string type variable. The value given here, will be shown as the window title.

WindowIcon

An window icon can be set. This variable contains the path of the icon.

ScreenResolution

A good number of screen resolutions are available. The default settings are: 640x480, 800x600, 1024x768, 1280x800, 1440x900.

FullScreen

This is a boolean variable. It can get one of the two values True or False.

2.2.2.2. Graphics Settings
RenderBackend

Currently, two backend renderers are available in FIFE. One is OpenGL and the other is SDL.

Lighting

FIFE supports three lighting models currently. Those are denoted by 0 (simple),1 (image) and 2 (animation). Any value greater than 2 throws an exception later.

BitsPerPixel

This field can only have four possible values: 0,16,24 and 32.

SDLRemoveFakeAlpha

This is a setting if somebody uses SDL as the renderer. It is not used anymore probably.

ColorKeyEnabled

It is a boolean variable for setting color key.

ColorKey

A string which denotes the rgb value of the color key comma seperated (r,g,b).

GLCompressImages

Enables or Disables image compression in the OpenGL renderer. Possible values are True' or `False.

GLUseFramebuffer

A boolean variable to enable or disable the use of the FBO. This is valid only if you are using the OpenGL renderer. Possible values are True or False.

GLUseNPOT

A boolean variable to enable or disable the use of non power-of-two textures. This is valid only if you are using the OpenGL renderer. If this is set to False the OpenGL renderer will automatically pad NPOT textures to make them POT. Possible values are True or False.

2.2.2.3. Sound Settings
PlaySounds

Another boolean variable. Giving it 'True' value keeps the sound on.

InitialVolume

Initially volume is a double value. It cannot contain any negative value and can never exceed the constant MAXIMUM_VOLUME which is 10.0 by the value.

2.2.2.4. Input Settings
MouseSensitivity

This is a Float value in the range of -0.99 (the slowest) and 10.0 (the fastest)

MouseAcceleration

Boolean variable. True enables mouse acceleration, False disables it.

2.2.2.5. Font Settings
Font

This is a string containing the path to the font file.

FontGlyphs

FontGlyphs are the characters that are defined in image fonts. These fonts are loaded directly from an image file and not from the ttf. FontGlyphs is of string type. All of the Font Glyphs should be given here with exactly same order they are present in the image file.

DefaultFontSize

We can assign a default font size here. If nothing is mentioned the default font size is 8.

2.2.2.6. Logging settings

Log manager provides convenient apis to access engine logging functionality.

Log targets can be set individually (prompt, file).

Things like visible modules can be adjusted through log manager.

LogModules

LogModules sets the modules that we need to log. There are a lot of modules that can be logged, e.g.: controller, video, audio, script etc. Write the module names semicolon seperated.

LogToPrompt

Tells the LogManager whether LogToPrompt should be set. If it is set to 1, log should be seen in the terminal or prompt.

LogToFile

Same as LogToPrompt, but here log is written to a file. Default name of the file is fife.log.

LogLevelFilter

Loglevel is used to set a treshold for output messages and related filter. There are four levels: LEVEL_DEBUG = 0, LEVEL_LOG = 1, LEVEL_WARN = 2, LEVEL_ERROR = 3, LEVEL_PANIC = 4. For example, in case log message has LEVEL_WARN, but the filter treshold is LEVEL_ERROR, log message is not outputted. Be sure to use LEVEL_PANIC, because it causes a program abort.

2.2.3. Miscellaneous settings

PychanDebug

Boolean variable. PychanDebug enables debug output for the pychan extension. If it is on, a lot of new debugging texts can be seen in the terminal.

3. Contributing

Interested in fife and want to help out? Do you see something that needs improving? Better yet, do you have a solution to one of our open issues?

You can support the project in all sorts of areas and we would graciously accept any contributions you have to offer! Please don’t hesitate, if you’ve got an awesome idea to throw into FIFE.

The best part about contributing to an open source project is you get the satisfaction of improving a project, not to mention full recognition for your work! It might help out on that next job application!

3.1. Help wanted…​

This is an open source project and developers are contributing on their own time. For this reason we are constantly looking for help.

We are looking for:
  • Engine developers - All skill levels in C++ and Python

  • Web designers - Our website needs an overhaul

  • Packagers - We want to improve or cross-platform build automation

  • Artists - They are always welcome to contribute some art where it’s needed

  • Documentors - We want to improve our manuals and API docs

Engine developers

We are in great need for all skill levels of developers to help with our C++ and Python extensions. There is work in just about any field you could imagine, from tool development, to OpenGL eye candy, to ear popping sound effects, to demo game development. You name it, we need it. Are you new to coding but want to learn? Are you an experienced coder looking for a project to fill that void in your life? This is the project for you!

Web designers

Currently our website is lacking a certain POW. It needs to be re-done in the worst way. We are completely open to your ideas as far as the backend goes. There is a template to start from here. You could either make some templates for our forums and blog or throw the whole thing out and surprise us with something else! It’s gotta look amazing to attract as much attention as possible!

Packagers

There is a bunch of work that needs to be done here. Our Windows installer needs work, our development kit needs updating, release packaging needs to be automated, the list is endless really. Currently we package every release by hand and this a tedious task so any help in this department would be great!

Artists

What project doesn’t need an artist or two? If you have some artistic skills and are looking for a project, look no further! We have several demos that would benefit from some new art (tilesets, gui art, icons, etc etc), not to mention our website!

Documentors

As they say, good documentation makes a project. This is one department, where it’s difficult to find people to volunteer their time to help out. Any time you can spend documenting fife or helping with tutorials would definitely help make fife even better!

3.2. Workflow

Here’s the most direct way to get your work merged into the project:

  • Fork the project.

  • Clone down your fork ( git clone git://github.com/<username>/fifengine.git ).

  • Create a topic branch to contain your change ( git checkout -b my_awesome_feature ).

  • Hack away.

  • If necessary, rebase your commits into logical chunks, without errors.

  • Push the branch up ( git push origin my_awesome_feature ).

  • Create a pull request against fifengine/fifengine and describe what your change does and the why you think it should be merged.

Please follow the [[C++ Coding Standards|coding-standards]] or [[Python Coding Standards|Python-coding-standards]] when modifying code.

3.3. Gotchas

  • Try to keep your patch(es) based from the latest commit on fifengine/fifengine. The easier it is to apply your work, the less work the maintainers have to do, which is always a good thing.

  • Please don’t tag your GitHub issue with [fix], [feature], etc. The maintainers actively read the issues and will label it once they come across it.

3.4. Finally…​

Thanks for helping us! We look forward to any contributions you make to help improve FIFE!

3.5. Working with Git

Need help with Github? Make sure to check the great Github Help Center!

Check out some very good git documentation here (including a cheat sheet): http://git-scm.com/docs

3.5.1. Basic git

3.5.1.1. Setting up your git environment

The first thing you should do when you first start running git is to set up some local variables.

Your name and email are very important as they will be part of every commit you make!

git config --global user.name "Your Name"
git config --global user.email your.email@gmail.com
3.5.1.2. Clone remote repository

To clone the fifengine repo with URL https://github.com/fifengine/fifengine.git in a specific directory on your machine

git clone https://github.com/fifengine/fifengine.git /path/to/your/projects/

A folder fifengine/ will be created at that location.

3.5.1.3. Update your local repository clone

Execute git pull in the fifengine/ folder.

3.5.2. Commit and Push

Users locally commit their changes to their working copy.

When they are happy with the outcome, they share these commits by pushing them to the remote server.

You need to either commit every change you did to your clone or select the files you want to update with the commit.

This is, amongst others, done with git add.

3.5.3. Examples

Add the changes in the two files export.h / module.h, move the index (of a file without changes) and remove a file as well:

git add engine/core/export.h engine/core/modules.h
git mv somefile.cpp newfile.cpp
git rm somefile.h

git rm also removes your local copy of that file! You can use the flag -- cached to prevent this.

Now you can use git status to check of everything fits what you want to commit.

3.5.4. Commit

If so, run git commit

and $EDITOR opens up, asking you for a commit message. When you save this file (and it’s not empty), the commit is executed.

GitHub has a blog post about commit message guidelines. See also this very helpful resource.

After that, you can push your changes to the remote repository with git push origin foo if you worked on the branch foo. Normally you will use git push origin master.

3.5.5. Undo

Edit your most recent, local commit

Just work like you would do with your regular next commit (edit files, git add and so on). When you’re done, type git commit --am and edit the old commit message to fit the appended additions as well.

This should only be used if you are sure that nobody worked on anything in the meantime!

Move to the most recent pushed commit

git reset --hard HEAD~1

Moving to any commit in general

Browse git log for the ID of the last commit you want to keep, removing every newer change. Then (with that ID) use

git reset --hard VERYLONGCOMMITSHA1

Most of the time git revert is what you are looking for.

It does a better job in reverting pushed commits (the two commits will be kept in the project history).

3.5.6. Branches and Merging

Branches are what makes git awesome! They are easy, fast and incredibly useful for distributed development.

Check which branch you are currently on, show all available branches

git branch

Change to another branch

git checkout origin/development

Track a remote branch

git branch -t development origin/development

Create new branch named foo

git checkout -b foo

Delete the branch named foo

git branch -d foo

If the branch was not yet merged, use -D instead of -d.

Try to merge the branch foo into your current branch

git pull . foo

Note that this will create conflict markers in each file where auto-merging is not possible.

You will need to resolve these conflicts manually — there are several tools to do so, see git mergetool.

When ready, you need to commit the resolved files.

The commit message will automatically indicate what kind of conflicts we had.

3.5.7. Patches and Diffs

If you are familiar enough with git, you may of course also customize the options given to the following. This is by all means only a recommendation and no rule to strictly follow.

Generate files containing the two most recent commits

After committing all your changes to a freshly-pulled repo, use

git format-patch -M -B -2

Where -4 instead of -2 would create patch files for the last four commits.

Applying such a file called 0001-user.patch is done using

git am 0001-user.patch

Note that the Unix tool patch does not need to support patch file renaming, so git am is the preferred way to apply patches. Useful flags might be --resolve.

-M -B handles renaming correctly to create smaller patch files, but this will then only be recognized by git (no unified patch anymore).

3.5.8. Committing patches of other authors

To correctly display who did what in our history, please use the following flags to git commit:

git commit --author "Author Name <email@example.com>"

If you already committed the files and now remembered you need to fix the author, use git commit --amend and proceed as above. This will edit the newest commit instead of creating a new one.

This is especially important for artists, who otherwise might not get proper credits. Ask them under which name and address they’d like to appear, then use that name consistently as Author Name.

3.5.9. Bughunting and History

Look up who introduced what in <path>

git blame <path>
git gui blame <path>

Check what happened in your repo

Use git log, git show, or git diff.

Find out which commit(s) cause a bug

Start with

git bisect good <tag/SHA where everything works>`

and

git bisect bad <tag/SHA where bug occurs>

Then continue to run the bisection with either entering git bisect good, if the bug does not show up or git bisect bad if it does. Repeating that, you will be presented a suspicious commit in the end: investigate there!

4. Coding standards

We have a set of quite detailed coding standards that have been followed for some time.

4.1. C++ Coding Standards

The following document describes our C++ coding standard.

4.1.1. Files

  • Headers files end with .h

  • Source files end with .cpp

  • Only one class per h/cpp file. (With a exception for classes that are extremely simple and clearly belong together.)

  • The files should be named after the (main)class they implement, but all in lowercase.

4.1.2. Conventions

4.1.2.1. Abbreviations and capitol letters

We use a mixture of upper and lower camel case (described below). There are some cases where you would be tempted to use to capitol letters together. This should be avoided! When using abbreviations in your variable or class names always capitalize the first letter of the abbreviation and lower-case for the rest.

class ColorRgb8;
class Dat1;
class Vfs;
class GlImage;
class SdlImage;
class GuiChanManager;

4.1.3. Classes

4.1.3.1. General guidelines
  • Name the class after what it is. If you can’t think of what it is that is a clue you have not thought through the design well enough.

  • Compound names of over three words are a clue your design may be confusing various entities in your system. Revisit your design. Try a CRC card session to see if your objects have more responsibilities than they should.

  • Avoid the temptation of bringing the name of the class a class derives from into the derived class’s name. A class should stand on its own. It doesn’t matter what it derives from.

  • Suffixes are sometimes helpful. For example, if your system uses agents then naming something DownloadAgent conveys real information.

4.1.3.2. Class names
  • First character in a name is upper case

  • Use upper case letters as word separators, lower case for the rest of a word

  • No underscores: _

  • Abstract classes should start with an I

Also known as "upper camel case". See the Camel Case article at wikipedia.

class MapView;
class IResourceManager;
4.1.3.3. Attribute/Member names
  • Start with a m_

  • Should not contain any more underscores

  • First word is lower case, the rest start with an upper case letter

RenderBackend* m_renderBackend;
uint16_t       m_frameLimit;
std::string    m_windowTitle;

This is also known as "lower camel case". See the Camel Case document at wikipedia.

4.1.4. Functions/Methods

4.1.4.1. General guidelines
  • Keep your functions simple.

  • Small functions that should be inlined go to the header file but after the class.

  • Use default parameters instead of inlined overloaded functions if you don’t have a reason not to do so.

so don’t write:

inline void doSomething() {  // Wrong
    doSomething(0);
}
void doSomething () {
    ....
}

write:

void doSomething(int32_t x = 0) { // Correct
     ....
}

4.1.5. Function/Method names

  • Use the same rules as for class names except the first letter should be lower case!

uint8_t getBitsPerPixel() const;
bool isFullScreen() const;

4.1.6. Variables and parameters

4.1.6.1. General guidelines
  • Don’t use global variables.

  • Do not put data definitions in header files.

    1. It’s bad magic to have space consuming code silently inserted through the innocent use of header files.

    2. It’s not common practice to define variables in the header file so it will not occur to developers to look for this when there are problems.

    3. Consider defining the variable once in a .cpp file and use an extern statement to reference it.

    4. Consider using a singleton for access to the data.

  • Don’t abuse the singleton objects so that they become global variable repositories. If you can’t access a variable easily from where you are you probably shouldn’t be accessing it from there. This is a rule of thumb, not to be enforced strictly.

  • Declare 1 variable on each line.

int32_t x, y, z; // Wrong

int32_t x;  // Correct
int32_t y;
int32_t z;
  • Align variable declarations as shown. This makes the code more readable.

int32_t     someVar1;
DWORD       someVar2;
std::string idSting;
  • Always initialize variables, and when initializing groups of variables align the code as shown.

someVar1 = 0;
someVar2 = 0;
idString = "";
  • When declaring pointers or references, the * or & is placed beside the type, not the variable name

int32_t* intPointer;
int32_t& intReference;
  • Use native types wherever possible. It is not necessary to "optimize" a loop counter by making it a uint8_t. Ideally, the use of such types would be restricted to three types of places:

    1. dealing with saving or loading the data (e.g. serialization/de-serialization routines)

    2. transmitting data over a network

    3. interfacing with external libraries, if those libraries absolutely insist.

4.1.6.2. Variable and parameter names
  • Parameter and local variables have no prefix and start with a lowercase letter.

  • Use capitol letters as word separators.

  • Variables and parameters should not contain underscores.

  • Include units in Names. If a variable represents time, weight, or some other unit then include the unit in the name so developers can more easily spot problems.

//Example variable and parameter names
IEngineChangeListener changeListener;
std::string           characterId;

//Including units in the name
uint32_t timeoutMsecs;
uint32_t myWeightLbs;

4.1.7. Types

4.1.7.1. Integer types
Specifier Equivalent on 64 bit platform Equivalent on 32 bit platform Signing Bits Bytes

int8_t

signed char

signed char

Signed

8

1

uint8_t

unsigned char

unsigned char

Unsigned

8

1

int16_t

short

short

Signed

16

2

uint16_t

unsigned short

unsigned short

Unsigned

16

2

int32_t

int

int or long

Signed

32

4

uint32_t

unsigned int

unsigned int or unsigned long

Unsigned

32

4

int64_t

long

long long

Signed

64

8

uint64_t

unsigned long

unsigned long long

Unsigned

64

8

4.1.7.2. Type Safety
  • Don’t use a #define when an enum or static const int32_t is also possible.

  • Do not use the C-style casts; instead use static_cast, dynamic_cast and reinterpret_cast (if really necessary).

4.1.7.4. Magic Numbers

Magic numbers are numbers that are compiled into the source code and if they are not properly documented can be difficult to understand what they do.

  • Instead of magic numbers use a real name that means something.

  • Use constants or enums to give meaning to the number.

const int WE_GOOFED = 19;

enum {
    THEY_DIDNT_PAY= 16
};

4.1.8. Coding Style

4.1.8.1. Line Widths
  • A line should not exceed 78 characters. The Main argument to do this is because this allows us to easily print readable source code (yes some of us still do this). Also if you have a wide monitor you can fit multiple source files side by side!

4.1.8.2. Braces
  • All braces use the following format.

if (x == y) {
    ...
} else if (x > y) {
    ...
} else {
    ...
}

while (condition) {
    ...
}

for (;;) {
    ...
}

rtype functionName() {
    ...
}
  • Even for trivial if statements always use the brace syntax.

if (x == true) {
    return;
}

This is clearer, less likely to cause future errors and has no effect on speed.

4.1.8.3. Indentation & Whitespace
  • Indentation is done by 4 spaces.

  • The content of a namespace is indented.

  • Don’t leave whitespace at the end of lines.

  • private:, public:, and protected: are in line with the class definition.

  • Code after private:, public:, protected: and case foo: is indented.

  • Emacs people: Emacs may use a mixture of spaces and tabs to indent. Make sure this feature is disabled.

namespace FIFE {
    class SomeClass {
    public:
        SomeClass();
        virtual SomeClass();
    protected:
        int32_t m_someval;
    };
} //FIFE

4.1.9. Includes

  • Try to use forward declarations rather to include other headers to reduce compiletime.

4.1.9.1. Platform specific includes
  • One of the issues with cross platform engine development are different include paths on different platforms. The FIFE team decided to introduce a set of helper include files to address this issue. You use these files instead of including the platform specific headers directly. Include these files after headers of the C++ std library but before any other 3rd party headers.

#include "video/opengl/fife_opengl.h"   (1)

#include "fife_unit_test.h"             (2)

#include "audio/fife_openal.h"          (3)

#include "util/base/fife_stdint.h"      (4)

#include "util/math/fife_math.h         (5)
1 Instead of including any OpenGL headers directly
2 Instead of including the boost unit test header <boost/test/unit_test.hpp> directly, use for tests that reside in tests/core_tests.
3 Instead of including any OpenAL headers directly
4 Instead of including the C99 stdint.h header directly
5 Instead of including the cmath header directly

4.1.10. Multiple Inheritance

  • In case you feel tempted to use multiple inheritance, read this first: http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.4 (the whole article is a good read).

  • In most of the cases, you can avoid multiple inheritance altogether with proper design. If you still feel urge to use it, try to use pure interfaces (no method implementations in addition to empty destructor). Prefix these classes with 'I'-letter (e.g. ITriggerController)

  • If you still feel that implementation multi-inheritance is the way to go, discuss this first with other developers.

4.1.11. Friend declarations

In general, don’t use friend declarations. Friends tend to get overused, since at first sight they provide quick and easy solution for problem at hand. In many cases however, they violate encapsulation and decrease modularity. There are cases where friends might be beneficial, but consult other developers before making the decision.

4.1.12. Error Handling

  • Use exceptions when something exceptional has happened and cannot be recovered from. Prefer to make an entry in the FIFE log and somehow recover. See the [[Developer guidelines|developer-guidelines]] page for more info on exceptions.

  • Constructors should always throw an exception on error conditions.

  • Destructors should never throw an exception.

4.1.14. Commenting

The level of commenting outlined here may seem excessive, but it will make the code much easier to understand when a new coder has to work with the system, something that will inevitably be happening in an Open Source project like FIFE. So please, don’t become lax with the commenting.

4.1.14.1. Headers
4.1.14.2. Implementation
  • Try to write code someone else understands without any comment.

  • If you need to do something uncommon, or some special trick, comment.

  • Don’t comment on something obvious.

4.1.14.3. Commenting Methods

All methods must be documented, no matter how trivial. The method description preceeds its declaration in the header file and uses standard doxygen notation. For simple accessor functions and things of similar complexity comments along the lines of the following are acceptable.

/** Short function description**
 *
 * @param p1 Short desc
 * @return Short description of return val
 */
rtype Function(ptype p1);

All methods' parameters and return types must be described. This is so that the doxygen generates documentation can be of real use. functions who’s use isn’t obvious require longer descriptions, which should include a more detailed description of its task as well as a sample of its use. Make the example as illustrative as possible.

/** Short function description
 *
 * Detailed description
 * @code
 * rtype rVal = complicatedFunction(param1, param2);
 * @endcode
 *
 * @param p1 Description of parameter
 * @param p2 Description of parameter
 * @return Description of return value.
 */
rtype complicatedFunction(ptype1 p1, ptype2 p2);

Comments inside the body of a method should be kept to a minimum in simple functions again. But in large functions, especially those that encapsulate key algorithms, relatively detailed descriptions of how the code is opperating will make it much more maintainable. These should be kept to one of two line comments using the // syntax.

// converts from screen space to world space
x += xoffset;
y += yoffset;

// checks to see if an image is already loaded.
bool loaded;
loaded = image->getImageData() != 0;
4.1.14.4. Commenting Variables

Member variables should all be commented. This is not a substitute for good variable names, but rather a way to make clear the use of each member variable.

//! Window width in pixels.
int m_windowWidth;

//! Window height in pixels.
int m_windowHeight;

//! SDL_Surface which represents the renderable area of the screen.
SDL_Surface* m_screen;

Parameters are all commented in the method description comment block so additional comments are unnecessary.

Descriptions of local variables shouldn’t be necessary as long as descriptive names are used.

4.1.14.5. Commenting Enums

When relevant all enums should be fully commented (including values). This only applies if the value names are not self explanatory.

/** An enum type. **
 * The documentation block cannot be put after the enum!
 */
enum EnumType {
    int EVal1, /**< enum value 1 */
    int EVal2  /**< enum value 2 */
};
4.1.14.6. Doxygen Tags

The following are not mandatory but it would be nice if everyone used them consistently.

@see

Use this to cross-reference another class/method/variable

@author

If you are the original author or major contributor of a class/method you might as well take credit for it. Multiple author lines are supported!

@since

If you are adding to the API you should mark which version of FIFE it will appear in first.

@deprecated

Use this keyword if a function/class is now deprecated and marked for removal.

@throw

When a method throws an exception you should document it using this keyword.

@pre

This describes some pre-existing condition that the following code relies on.

/** Pretty nice class.**
 * This class is used to demonstrate a number of section commands.
 *
 * @author John Doe
 * @author Jan Doe
 * @since 0.3.4
 * @deprecated Do not use in v0.3.5+. Replaced by EvenNicerClass.
 * @see EvenNicerClass
 * @pre First initialize the system.
 * @bug Not all memory is freed when deleting an object of this class.
 * @warning Improper use can crash your application
 */
class SomeNiceClass {};

4.1.15. Doxygen Tags: Gotchas

Along with other comments, use gotcha keywords to mark unfinished tasks in the code. Doxygen will parse your comments looking for these keywords, and making a report, so people can make a special effort where needed.

@todo

Means there’s more to do here, don’t forget. Can include known issues and bug or issue numbers if needed.

@bug

This indicates that there is a known bug with the code. Be descriptive! Include bug or issue numbers!

@warning

Use this when you need to bring special attention to whatever you are documenting. Perhaps there is a usage restriction or assumption that the user should know about!

4.1.15.1. Including examples in your comments

For simple examples you can use @code and @endcode.

/** This is an awesome class.**
 * It's made of pure awesomeness and should be used sparingly
 * as to not waste the awesomeness.
 *
 * @code
 * AwesomeClass ac;
 * ac.doSomethingAwesome();
 * @endcode
 */

4.1.16. License

  • If you directly copy and paste code from another project the original copyright header needs to stay in place! Don’t add a FIFE header to the file in this case.

  • If you used portions of code from other projects and integrated it into project files, add the FIFE header at the top of the file but add an additional remark after it that states the origin of the copied code parts.

  • You can use this example as a template in this case:

/***************************************************************************
 *   Copyright (C) 2005-2013 by the FIFE team                              *
 *   http://www.fifengine.net                                              *
 *   This file is part of FIFE.                                            *
 *                                                                         *
 *   FIFE is free software; you can redistribute it and/or                 *
 *   modify it under the terms of the GNU Lesser General Public            *
 *   License as published by the Free Software Foundation; either          *
 *   version 2.1 of the License, or (at your option) any later version.    *
 *                                                                         *
 *   This library is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 *   Lesser General Public License for more details.                       *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
 ***************************************************************************/

4.2. Python Coding Standards

We use a slightly modified version of the official [Style Guide for Python code](http://www.python.org/dev/peps/pep-0008/) as a basis for our coding standards. This article describes our modifications and additions and also contains a summary of the coding standards. Reading the official style guide is highly recommended before moving on, as this article merely complements it.

4.2.1. Files

  • Python files end with .py

  • Only one class per py file. (With a exception for classes that are extremely simple and clearly belong together.)

  • The files should be named after the (main)class they implement, but all in lowercase.

Executable python files

Python files which are meant to be executed directly, should have a shebang on the very first line. If your python file is not made for direct execution, it should not have neither a shebang.

The shebang we use is: #!/usr/bin/env python

4.2.2. Naming Conventions

4.2.2.1. General
  • Internal or non-public variables, functions or classes are prefixed with an underscore

  • If you really do not want subclasses or other parts of python to use a member or method, prefix it with two underscores to invoke python’s name mangling

4.2.2.2. Package and module names
  • Module names are named after the class it contains, but all lowercase

  • Package names are also lowercase. Do not use underscores: _

4.2.2.3. Class names
  • Class names use CamelCase. Example: TestFactory, not test_factory, testFactory, Test_Factory, etc.

4.2.2.4. Function and method names

This differ from python style guide * Function names start with a small letter. (Example: def getRoofVisible())

4.2.2.5. Function and method arguments
  • Always use self for the first argument to instance methods. (Example: def setVisible(self, visible):)

  • Always use cls for the first argument to class methods

TODO: Write an example

4.2.2.6. Variables and constants
  • Class members start with a prefix _ and are all lowercase (Example: _roofshift_x )

  • Parameter variables have no prefix and are also all lowercase. (Example: myparamvar)

  • Local variables have no prefix and are all lowercase. (Example: mylocalvar)

  • Constants are all uppercase with underscore separating the words. Example: MAX_LINES

4.2.3. Coding Style

4.2.3.1. Indentation & Whitespace
  • Indentation is done by a real tab. This differs from python style guide!

  • Use 4 spaces per indentation level.

  • Never mix tabs and spaces!

  • Don’t leave whitespace at the end of lines.

  • Emacs people: Emacs may use a mixture of spaces and tabs to indent. Make sure this feature is disabled.

4.2.3.2. Blank lines
  • Separate top-level functions and class definitions with two blank lines.

  • Method definitions inside a class are separated by a single blank line.

  • Extra blank lines may be used (sparingly) to separate groups of related functions.

  • Use blank lines in functions, sparingly, to indicate logical sections.

4.2.3.3. Imports
  • Only one import per line

# Yes:
  import os
  import sys

# No:
  import os, sys
  • Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.

  • Imports should be grouped in the following order, separated by a blank line:

    1. standard library imports

    2. related third party imports

    3. local application/library specific imports

  • Always use the absolute package path for all imports.

4.2.3.4. Functions
  • Keep your functions simple.

4.2.3.5. Arguments

Avoid using boolean parameters and if you need them, supply as keywords arguments. If you use them and you can supply the as positional arguments - don’t. The rationale here is that the meaning of boolean arguments is very difficult to see for the reader otherwise:

  # Bad - What does the arg mean? Don't layout?
  self.adaptLayout(False)

  # Good - At least the reader has an idea what the arguments means.
  self.adaptLayout(recurse=False)
4.2.3.6. Multiple Inheritance
  • In case you feel tempted to use multiple inheritance, read this first: http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.4 (even the whole article is a good read).

  • In most of the cases, you can avoid multiple inheritance altogether with proper design. If you still feel urge to use it, try to use pure interfaces (no method implementations in addition to empty destructor). Prefix these classes with I-letter (e.g. ITriggerController)

  • If you still feel that implementation multi-inheritance is the way to go, discuss this first with other developers.

4.2.4. Commenting

TODO: Add class documentation.

The level of commenting outlined here may seem excessive, but it will make the code much easier to understand when a new coder has to work with the system, something that will inevitably be happening in an Open Source project like FIFE. So please, don’t become lax with the commenting.

This is even more important as we only provide the engine. Remember each comment might fix a misunderstanding and thus problem for the game devs using FIFE.

Write the public documentation and comments from the point of a user.

4.2.4.1. Implementation
  • Try to write code someone else understands without any comment.

  • If you need to do something uncommon, or some special trick, comment.

  • Don’t comment on something obvious.

4.2.4.2. Commenting Files

All files should have a documentation string. That is the place to document the interaction and purpose of the module. You should link to most relevant classes and functions for the module. Try to explicitly state bugs, shortcomings and the dark and fuzzy areas of the code which need improvement.

  """
  Foo Module
  ==========

  ...

  Performance Issues
  ------------------

  If you encounter performance issues with the Foo class. Remember
  That the @L{FooSet.findSomething} method needs to iterate over all
  foo instances. Do not use it in an inner loop. Instead use @L{getQueryDict}.

  Good::
    d = foo.getQueryDict()
    for name in names:
       for foo_instance in d.get(name,[]):
          doSomething( foo_instance )

  Bad::
    for name in names:
       for foo_instance in foo.findSomething(name):
          doSomething( foo_instance )
  """

4.2.5. Commenting Methods

All methods should be documented, no matter how trivial. Here’s an example of how to document using epydoc style. If possible link to other relevant functions, provide a use case and give information on the expected results of the function.

 def findSomething(self, param):
    """ Find all instances of foo, which match param

    Matching is performed by string comparison @C{foo.name == param}.
    See @L{querySomething} for more complex queries.

    Example::
       fooList = stuff.findSomething("some")
       for x in fooList:
           print x.name # This will print 'some'
    """

Comments inside the body of a method should be kept to a minimum in simple functions again. But in large functions, especially those that encapsulate key algorithms, relatively detailed descriptions of how the code is operating will make it much more maintainable.

 # converts from screen space to world space
 x += xoffset
 y += yoffset

 # checks to see if an image is already loaded.
 loaded = image.getImageData() is not None

4.2.6. Commenting Variables

Member variables should all be commented. Either individual variables, or blocks of variables with a similar function, as long as all member variables are in some way described. This is not a substitute for good variable names, but rather a way to make clear the use of each member variable.

The documentation should be in the init function.

 def __init__(self):
    # Initialise the window size with sane defaults.
    self.window_width = self.DEFAULT_SIZE[0]
    self.window_height = self.DEFAULT_SIZE[1]

    # The command object handles all our commands.
    # We proxy in the doXYZ() methods.
    self.command = CommandObject(self)

Parameters are all commented in the method description comment block so additional comments are unnecessary.

Descriptions of local variables shouldn’t be necessary as long as descriptive names are used.

4.2.7. Gotchas

Along with other comments, use gotcha keywords to mark unfinished tasks in the code.

TODO

Means there’s more to do here, don’t forget.

FIXME

Means there’s a known bug here, explain it and optionally give a trac id

4.2.8. License

4.2.8.1. FIFE Python header
# -*- coding: utf-8 -*-

# ####################################################################
#  Copyright (C) 2005-2013 by the FIFE team
#  http://www.fifengine.net
#  This file is part of FIFE.
#
#  FIFE is free software; you can redistribute it and/or
#  modify it under the terms of the GNU Lesser General Public
#  License as published by the Free Software Foundation; either
#  version 2.1 of the License, or (at your option) any later version.
#
#  This library is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#  Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public
#  License along with this library; if not, write to the
#  Free Software Foundation, Inc.,
#  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
# ####################################################################

4.3. Coding Standard Checkers

4.3.1. Formatting C++ code with Astyle

We use ArtisticStye (astyle) for coding style checks and automatical formatting of C++ source code. You find the .astylerc configuration file in the fifengine repository.

Installation of astyle

Linux:

apt-get install astyle

Windows:

Usage

# Check style
astyle --recursive --options=.astylerc "engine/core/*.h" "engine/core/*.cpp"

4.3.2. Formatting Python code with Pylint

We use the pylint for coding style checks and automatical formatting of Python source code. You find the .pylintrc configuration file in the fifengine repository.

Installation of pylint

# Install pylint (installs pylint.exe in %PYTHON%\Scripts)
python -m pip install pylint

Test run:

%PYTHON%\Scripts\pylint --version

Usage

To check all Python files in the folder ./engine/python/fife/ run:

- pylint --rcfile=.pylintrc ./engine/python/fife/

5. Fife Windows SDK

The Fife Windows SDK is a collection of software development tools for working with Fifengine.

The Fife SDK installer build scripts fetch all required packages for working with fifengine, including build-tools and dependencies, prepares them for packaging and finally builds the "SDK" installer on Appveyor.

This chapter documents these build scripts and tasks, including fetching and extracting components and compiling the InnoSetup installers.

5.1. Repository Overview

Let’s start with an overview of the files and folders in the fife-windows-sdk repository:

├──build-scripts
│   ├── 1-download.bat
│   ├── 2-extract.bat
│   ├── 3-copy.bat
│   ├── 3-stripdown.bat
├──build-tools
│   ├── 7zip
│   ├── aria2
│   ├── innosetup
├──download-lists
│   ├── fifengine.txt
│   ├── fifengine-build-tools.txt
├──installer
│   ├── images
│   │   ├── fife.ico
│   │   ├── WizardImage.bmp
│   │   ├── WizardImage.xcf
│   │   ├── WizardSmallImage.bmp
│   │   ├── WizardSmallImage.xcf
│   ├── includes
│       ├── envpath.iss
├── appveyor.yml
├── CHANGELOG.md
├── LICENSE
├── README.md

5.2. Appveyor

We are using Appveyor to continuously build and publish the installer. The file appveyor.yml is Appveyor’s configuration file. Important are the sections before_build, build_script, artifact, deploy.

5.3. Before Build Tasks (before_build)

Before we can build the installer, we need to download and extract the software components, which we later want to include in the installer. After the extraction, we copy and move some files and folders around. Then we delete several unnecessary files and folders in a stripdown run.

At the end of the before_build step, we have a proper folder structure with all the components we want to ship, ready for inclusion into the installer.

5.4. Building the Installer (build_script)

The installer is build using the InnoSetup Compiler (iscc).

The property APP_VERSION is set from the APPVEYOR environment as %APPVEYOR_BUILD_VERSION%, so that the installer is dynamically versionized from the outside.

build-tools\innosetup\iscc /DAPP_VERSION=%APPVEYOR_BUILD_VERSION% installer\fife-sdk.iss

The target location for installer is: fife-windows-sdk\_build.

The compiled setup executable has the following naming scheme: {#APP_NAME}-{#APP_VERSION}-Setup-{#APP_COMPILER}-x86,

for example: _build\FifeSDK-0.4.0-Setup-VC14-x86.exe"

5.4.1. Debugging the installer

  • You can create a log of the installation procedure by using the /LOG CLI argument.

    FifeSDK-0.4.0-Setup-VC14-x86.exe /LOG=c:\fifesdk.log

5.5. Artifact Upload (artifact)

When the installer was successfully build, it is automatically published on Appveyor’s artifact storage.

5.6. Downloads (deploy)

When a new release version of the installer is tagged, then the installer is automatically published on Github Releases.

6. Image Atlas Creator

The Image Atlas Creator allows users to combine multiple images into an image atlas. This reduces the number of files you need to ship with your game and speeds up rendering!

The tool is written in C++ using Qt.

6.1. Usage

TODO

6.1.1. Input

The supported Image File Types are: - png - jpg - jpeg - tga - bmp

See Source

TODO

Dependencies

Fifengine Dependencies

The following dependencies are needed to build FIFE from source:

  • Frameworks

  • Sound libraries

  • Graphics and GUI libraries

    • opengl >= 1.3 optional for OpenGL support

    • GLEW

    • fifechan >= 0.1.0 optional

    • libpng

  • Python scripting-related libraries

  • Compression libraries

  • Serialization / XML libraries

  • Linux specific

    • Xcursor

FifeChan Dependencies

FifeChan is a C++ GUI library. It has several optional dependencies. The following dependencies are needed to build FifeChan from source:

  • Allegro support

  • OpenGL (check drivers from your graphics card vendor)

    • Optional OpenGL Contrib Dependencies (Set ENABLE_OPENGL_CONTRIB to ON if you need them)

  • SDL support

Atlas Creator Dependencies

The Atlas Creator depends on

Checklist for new dependencies

In case a library gets outdated and has to be replaced or you want to introduce a completely new 3rd party library you should ensure it meets the following guidelines:

  • Cross-platform support (Linux, Windows, Mac)

  • Widely used by other projects and has an active community

  • Available to download as a package for most platforms

  • Has been in active development for a number of years

  • License is compatible with fife

Glossary

The glossary helps to ease communication between developers and users of fifengine by defining a set of commonly agreed upon terms.

Agent

An agent is a dynamic map instance. It can move to different map locations at runtime.

Animation

Sequence of image files that are played in succession to create illusion of e.g. walking. See http://en.wikipedia.org/wiki/Animations

Archetype

Archetypes hold the basic data used in maps and throughout the game. They provide the IDs and names used in the Map Format.

Atlas

Atlas or Image Atlas groups together several smaller images into a larger one for performance benefits.

Backend

Backend From Wikipedia: "In software design, the front-end is the part of a software system that interacts directly with the user, and the back-end comprises the components that process the output from the front-end. The separation of software systems into "front ends" and "back ends" is a kind of abstraction that helps to keep different parts of the system separated."

Camera

A viewport or scene. Multiple cameras can exist with different scenes being portrayed on each camera.

Client

A game or tool that uses FIFE as it’s engine.

Console

Console is an in game window that can be used to type commands for fife engine.

Content

Media (images/music/sound fx/font/etc), map files, or GUI definition files.

Contributor

Contributors are people working on FIFE on an occasional basis. Contributors have no write access to the FIFE Git repositories. Collaboration is done by forking a repository and sending patches back to the upstream repository via a Github pull request.

Dataset

TODO

Developer

Developers are people working on FIFE on a regular basis. They have write access to the FIFE Git repositories.

Elevation

Map consists of elevations. Elevation can be thought as a floor in case you think map being a building. Each map has to have at least one elevation.

Event

TODO

FifeChan

FifeChan is a C GUI library (libfifechan). It's the successor of GuiChan. The pythonic binding to the C API is called PyChan.

Game creator

A single person or a whole team of individuals who create a FIFE-based game.

Gamma level

TODO

Geometry

TODO

Gid

Graphical ID. Used to uniquely identify any piece of graphic inside a set of related xml-file fragments.

Grid

TODO

Layer

TODO

Location

TODO

Map

World presentation from FIFE perspective. See Map model.

Metamodel

TODO

Model

TODO

Object

TODO

Offset

TODO

Palette

TODO

PyChan

PyChan is the pythonic binding to the C++ API of the GUI library FifeChan.

Spritesheet animation

Specific type of atlas that represents only one action (animations for all defined directions). Typically, it’s one direction per row, one frame per column.

Tid

Tile ID. Same as Gid, but used only for tile related graphics.

Tile

TODO

Tileset

TODO

User

The term user is often utilized for expressing that the respective person is neither a developer nor a contributor of the development team.

Visual

TODO

View

TODO