\documentclass[twoside]{book}
\usepackage{linuxdoc-sgml}
\usepackage{qwertz}
\usepackage{url}
\usepackage[latin1]{inputenc}
\usepackage{t1enc}
\usepackage[english]{babel}
\usepackage{epsfig}
\usepackage{null}
\def\addbibtoc{
\addcontentsline{toc}{section}{\numberline{\mbox{}}\relax\bibname}
}%end-preamble
\title{Linux Games Install And Directory Guide
      }
\author{Ingo Ruhnke, {\ttfamily grumbel@gmx.de}
      }
\date{v0.3, Begin: Tue Aug 17 23:11:43 1999, Last update: Wed Aug 25 23:59:18 1999
      }
\abstract{      This document gives an overview how to install games under
        Linux and how to put the files in the correct directories
        according to the FHS.
      }


\begin{document}
\maketitle
\tableofcontents

\section{What is different between DOS/Windows and Linux?
      }

DOS and Windows use a very simple way of handling the
directories. If you install a program, all data goes to a
single directory. The program don't has to worry about were
to place the files, it can handle that as it likes to do.

Under Linux the thing looks a bit different, the complete file
system is only one big tree, there is no separation into
different drives and the data of a program is spread
over this filesystem tree. There is a standard document, the
Filesystem Hierarchy Standard, which describes where the files 
belong, most games which I know do not follow this standard
or following only some of its rules.

For standard software
documentation goes to {\ttfamily /usr/doc/}, binaries go to
{\ttfamily /usr/bin/}, data files to {\ttfamily /usr/share} and
so on.  This has different reasons,
one of them is that you should be able to mount
the {\ttfamily share/} directory remote over a network, since it
should only contain system independent files, while
{\ttfamily bin/} for example contains system depended binaries
which can't be shared over different machine types. For games
there are some special directories reserved, they differ a bit 
from the standard directories, but not much. A lot of games at
the moment don't use that directories, this document should
give a introduction on how to handle all that directories and
how to avoid trouble.




\section{The directories and how to handle them
      }


\subsection{The different between {\ttfamily /usr/} and
          {\ttfamily /usr/local}.
        }

Before I start with some more detailed description, there
is one thing you should know. There is a directory tree
{\ttfamily /usr} and there is a directory tree {\ttfamily /usr/local},
they contain both the same subdirectories, but the different 
is that {\itshape all\/} stuff under {\ttfamily /usr} is handled by 
the distributions package system, while all stuff under
{\ttfamily /usr/local} is maintained by the system
administrator. So if you are providing a game as source or
as a precompiled tarball it has to go to
{\ttfamily /usr/local}, if you provide instead or in addition
{\bfseries RPM} or {\bfseries debian packages} they should install
them self into {\ttfamily /usr}. In the following text I will
refer only to {\ttfamily /usr}, because things under
{\ttfamily /usr/local} are the same just in another prefix
directory. 


\subsection{Which files are needed by a game?
        }

So before we a going to install a game we first have to
think which files we have in a game and what types of files
are they. Most games will have some or most of the following 
file types:

\begin{itemize}
\item binaries (executables)
\item graphics (*.pcx, *.tif, *.jpg, etc.)
\item musics (*.mp3, *.wav, *.mod, *.midi, etc.)
\item sounds (*.wav, *.voc, etc.)
\item packed datafiles (*.wad, *.dat, etc.)
\item levelfiles
\item shared libraries (*.so)
\item script files
\item save games
\item hiscore files
\item config files
\item etc.
\end{itemize}





\subsection{Where to put the files?
        }


\subsubsection{Binaries - /usr/games/
          }

This is the easiest thing to do correct. Normal programs
are placed under {\ttfamily /usr/bin}, while games get their
own directory under {\ttfamily /usr/games/}. So all user 
visible binaries should go directly into that directory, this will
be mostly just a single executable binary.




\subsubsection{Static Datafiles - /usr/share/games/
          }

A lot of games at the moment put there data files in a
place like {\ttfamily /usr/lib/\$GAME}, but games will now get there
own directory so placing them into {\ttfamily /usr/lib/} wouldn't be
the correct way. The new place for static game data is
{\ttfamily /usr/share/games/\$GAME}. All {\itshape static\/} and
{\itshape architecture independent\/} goes to that directory,
like images, music files or packed datafiles. It is not
required to separate the directory any further, but I
recommend it, since it will ensure that you will not end up
in chaos, if the project groves.




\subsubsection{Shared library's - /usr/lib/games/
          }

Some games use shared libraries which are linked at run time,
this allows the game much more flexibility, because levels
and enemy's can be created in C or whatever language they
might choose, so there is no need for scripting languages or 
other stuff to make the game more flexible. You might
guess that libraries should also 
placed under {\ttfamily /usr/share/}, but that is not correct. Since 
{\ttfamily /usr/share/} is only for architecture independent files
and shared libraries are not architecture independent, they 
depend on a specific type of machine architecture. So
they should be placed under {\ttfamily /usr/lib/games/\$GAME/}.




\subsubsection{Save games - \$HOME
          }

A lot of games offer the possibility to save the game
status and restore the state where you left the game. This
data is variable and should therefore not saved  
under {\ttfamily /usr/*}. So were to put the savegames? Because 
savegames are personal data, there are best placed into the
users home directory. The savegames should be placed in an
extra directory for each game, like {\ttfamily \$HOME/.\$GAME/}.
This will ensure that the directory is normally hidden
and won't annoy the user. If there is more variable user
specific data (like demo files, etc.) it should also be
placed in that directory. Then the directory should be
separated into some subdirs like {\ttfamily save/} and
{\ttfamily demo/}.




\subsubsection{Hiscores - /var/games/
          }

Hiscores are similar to save games, but they are not
equal. The different is that save games or mostly interesting 
for personal use, while hiscores are interesting for
other. On a multiuser system it would be interesting to
fight against other peoples hiscores. So hiscore files and
other dynamic data which is not meant for personal use only
should be placed under {\ttfamily /var/games/}. If the game
needs more then one file to hold the data it should get its
own subdirectory, like {\ttfamily /var/games/\$GAME}




\subsubsection{Config files - /etc \& \$HOME
          }

As for all other programms, there are two places for config
files, one is {\ttfamily /etc/} and the other is the users home 
directory. I'd recomment to use an extra directory for games 
under {\ttfamily /etc/}, but the FHS does not require
this. So {\ttfamily /etc/games/}  
should be the places where the global config files where
placed. Local user config files should be placed under
{\ttfamily \$HOME/.\$GAME/}, just like save games.




\subsection{How to find the files and how to make the game relocatable?
        }

Now you know where to put all files, but how to find them
after installaton? If the game is compiled from source it is
easy, the install prefix, which should be {\ttfamily /usr/local}
by default, should be compiled into the binary. How to do this
using autoconf/automake is discribed below, if you are using a
non standard way, you have to do that yourself or switch to
autoconf/automake, which is really recommend. This way the game
will allways know where it was installed.

The problems come
when you are trying distribute a binary version. If the game is packed
in a debian or RPM package, then the package maintainer should
set the prefix right so that the game will run fine after
installaton. But what if the user wants to install the game
somewhere else, for example under {\ttfamily /opt}? Then the game
has to be relocatable. But what does relocatable mean? Its
means that you can install a programm where ever you want it
to be, you are not forced to use the standard directories.
There should be allways a way to override the default path 
in a game. A good possibility to do that is to set the prefix
directory throu a configuration file, an enviroment 
variable (\$GAME\_DATADIR or \$GAME\_PREFIX) or an command line
option, for example {\ttfamily --data-dir}.




\subsection{How to allow extra levels or similar stuff?
        }

The problem that arrived with extra levels and similar stuff
is that not all users have root access to there macines, so it 
is not possible or to difficult to place the files under {\ttfamily /usr}
or it would be more comfortable to have them in the home
directory when you are developing a level. Therefore the game
should offer the possibility to read the files from
{\ttfamily \$HOME/.\$GAME/}. The subdirectory structure in that
directory should be equal to that in
{\ttfamily /usr/share/games/\$GAME}, so it will be possible to
extract the extra level in {\ttfamily /usr/share} or in {\ttfamily \$HOME/.\$GAME}, 
without tweaking the path.

{[}FIXME:] At the moment I am not having much experience with shared
libaries, so I can not say if it will cause throuble to
placing them under {\ttfamily \$HOME/.\$GAME/}. I think the
LD\_LIBRARY\_PATH has to be adjusted, but I am not sure.




\subsection{How to handle data from a cd-rom?
        }

{[}FIXME:] This section is only theoretical, I never tested anything from 
below, so be warned!

Under DOS and Windows handling the cdrom wasn't very difficult 
the game only needs to now the drive letter. Under Linux the
situation is not much different, but instead of a drive letter 
we have a device name where the cd-rom is and a directory name 
where the cd-rom is mounted. The standard places are on the
most machines {\ttfamily /dev/cdrom}, which is a link to the correct
device (you normaly will newer want to touch this directly)
and the directory {\ttfamily /cdrom}. But the correct 
location should be always be detected at installation
time and stored in a human readable configuration file.

Some games allow it to install only 
some files to the harddrive and let all other data resist on
the CD or to install all data to the harddisk. This
shouldn't be to hard to include 
into a game, it only has to keep track of were it installed it 
files and then load them were there were installed. I
recomment it to have a similar directory structure on the
cdrom as on the harddisk, since that makes thing easier, so
the programm can acces its data with:

\begin{tscreen}
\begin{verbatim}
              f = fopen(make_full_path("levels/level1.dat"), "rb");
              ...
            
\end{verbatim}
\end{tscreen}


Where {\ttfamily make\_full\_path()} is a function translating the
relative path (here: {\ttfamily levels/level1.dat}) into a full
path, which could be {\ttfamily /cdrom/levels/level1.dat} or
{\ttfamily /usr/share/games/GAME/levels/level1.dat}, depending on 
which data was installed. Another more tricky possibility
would be to use  
symlink. The install scripts would create symlinks for all
files which aren't installed and let this symlinks point to
the cdrom directory, that would be possible, but cause some
trouble when the cdrom is mounted to another directory or
the computer as multiple cdrom drives.




\section{How to install the game?
      }

Now as we made clear where all the files should go. The
question is how to install the game? The game can come into 
source or binary form, can use just a few MB's or thousand of
them. If the game is small it is the best to just use the
standard ways of installing software under Linux, which are
tar.gz files containing the source, or for binary distributions 
use packages files like RPM or debian packages, you can also
use tar.gz binary distribution, but then they would not check if
the correct libraries are installed, that causes lots of trouble
for example with mixed libc5, glibc2.0 and glibc2.1
installation. So if you are not having much time while developing its better to 
not start creating tar.gz binaries and instead make the source 
as easy compile able as possible. 




\subsection{How to install the source?
        }

The source package should {\itshape always\/} be a tar.gz file
which installs in a single directory tree and is after
unpacking installable with a:

\begin{tscreen}
\begin{verbatim}
              $ ./configure
              $ make
              $ make install
          
\end{verbatim}
\end{tscreen}


This way of installation is the standard way for most
software and is very common for the most users, so it will
cause the lessest trouble. This way can be easily obtained
with autoconf and automake. If you are using a non standard 
way of doing installations, you should change it to the
lock and feel of the above or even better switch over to
automake and autoconf, since it will give you all that and
also stuff like automatic distribution packaging and library
checking, etc.




\subsection{How create packages?
        }

The task of package creation is more or less complex. You
can probably get some simple packages to work for your distribution, but
maintaining different packages for different distribution,
which you don't have, is probably a bit hard, since you
can't test them easily. It is a very good idea to find
somebody who will packaging the stuff for you and test it,
this will save you a lot of work and ensure that the package 
will work.




\subsection{How to handle CD-Rom installation?
        }

If your game is very big, so that it is distributed on CD,
there could be some trouble. Packages of your program will
be impossible, since you would have to distribute three or
more different packages (.rpm, .deb, tar.gz), that will
probably blowup the CD space. So the easiest solution is to
just distribute a tar.gz file with a installation script and 
documentation on how to do the installation manually. The
install script should ask what the user wants to install and 
where to install it, it should also create a install log, so 
that the game find its datafiles after installation without
user interactions. The script should probably perform the
following task:

\begin{itemize}
\item Ask what to install (videos, level data, etc.)
\item Ask where to install ({\ttfamily /opt}, {\ttfamily /usr}, {\ttfamily /usr/local}, etc.)
\item Install the data
\item Make sure that the game will find its data (create a 
config script or tell the user which enviroment variables he has to set)
\end{itemize}





\subsection{How to create update or patch distribution?
        }

If you release a new version of your package it is a good
idea to also make a patch or update available, so that the
user is not forced to download the complete game again.




\subsubsection{Using diff/patch
          }

If you changed only the source, you can create a patch
file, with diff. The patch file can be applied using
patch. For more informations see {\ttfamily info patch} and
{\ttfamily info diff}. The problem is that diff/patch can't
handle binary files, so it is impossible to use them with
alone if you changed some datafiles or changed the
directory layout.




\subsubsection{Using hand build update scripts
          }

If you changed the directory layout or added some new
files you will have to use a hand build update script.
The script should first check for the games install directory
and than start patching  and updating.


\subsubsection{Patching a RPM
          }

If you distributed your game as RPM you might ask, but how 
to patch that? A way to do that was mentioned by Pierre
Phaneuf $<$pp@ludusdesign.com$>$. You could create an
update script and a Source RPM, the script will
than catch all the installed datafiles from their
directories, build a new RPM from the Source RPM using the
datafiles and then install the new RPM. But aware that
this is only theoretical and was never been tested in
practice. 


\section{Some tips about of to make that with automake/autoconf?
      }


\subsection{Tweaking the path
        }

The problem with automake, which I really recommend to use, is 
that it installed the files at default in the normal places,
thats perfectly OK, but since games are a bit different there
is the need to tweak the pathnames a bit. That can be done by
placing the following in the {\ttfamily Makefile.am}'s

\begin{tscreen}
\begin{verbatim}
              # Tweaking the `datadir' to install the files in the correct location
              pkgdatadir = $(datadir)/games/@PACKAGE@
            
\end{verbatim}
\end{tscreen}





\subsection{How to find out where the package is installed?
        }

If you are using automake/autoconf the user has the choice
to override the default prefix, which is
{\ttfamily /usr/local}. So the question is how to I get the
install directory? Therefore we have to hardcode the path
into the binary, but how to
accomplish that? The problem is that we need to expand the
variable {\ttfamily \$prefix} to the full pathname, else we would end up with
a useless string like {\ttfamily "\$prefix/"}. Place the following in the file
{\ttfamily acinclude.m4}: 

\begin{tscreen}
\begin{verbatim}
              AC_DEFUN(MY_EXPAND_DIR, [
                $1=$2
                $1=`(
                     test "x$prefix" = xNONE && prefix="$ac_default_prefix"
                     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
                     eval echo \""[$]$1"\"
                    )`
              ])
            
\end{verbatim}
\end{tscreen}


And the following into {\ttfamily configure.in}:

\begin{tscreen}
\begin{verbatim}
              MY_EXPAND_DIR(game_datadir, "$datadir/games/$PACKAGE")
              AC_DEFINE_UNQUOTED( GAME_DATADIR, "$game_datadir")
            
\end{verbatim}
\end{tscreen}


This will create a macro called GAME\_DATADIR, which will
expand into the path where your game data resist. For
example if the game is installed into {\ttfamily /usr/local} GAME\_DATADIR 
will expand to {\ttfamily /usr/local/share/GAME/}, when you
need other data then the one that resist in {\ttfamily share/\$GAME}
you can also use {\ttfamily "\$prefix"} in the example.

\end{document}
