How Linux Games should Install

From Wikiid
Revision as of 19:18, 23 October 2007 by SteveBaker (Talk | contribs) (New page: When a game (or other complex application) starts up, it typically does not know where it was installed - or where its data files live. We don't want to have to search the entire filing s...)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

When a game (or other complex application) starts up, it typically does not know where it was installed - or where its data files live. We don't want to have to search the entire filing system (and in any case, with multiple versions of the application installed, that wouldn't even work). We don't want the end user to have to change directory into the game's own directory - and we ideally don't want the end user to have to do anything more than type the name of the game and hit 'return' - or to click on a desktop icon. It should "just work".

File system standards don't help

The Free Standards Group logo

The FHS (Filesystem Hierarchy Standard) and the LSB (Linux Standard Base) before it, define a standard file system organisation.

In theory, all games (and other applications for that matter) should be slotted into their correct places in that hierarchy - and it should then be perfectly clear where things should be installed - and applications would then have no problems finding their data files because they would reliably be in the exact same place every time.

The problem is that FHS, LSB and other 'standards' are not enforcable (nor should they be). Whilst a package installed as a part of a Linux distribution would likely follow the rules, someone who installes your game themselves are unlikely to. I can tell you from painful experience that end users will want to put your game exactly where they want to put it - and to hell with any standards.

Their reasons are many - but here are some of the more valid ones:

  1. "I don't have any space left on that partition"
  2. "My IT department have write-protected that directory and I don't have root privilages"
  3. "That directory is on an NFS partition and our network is too slow to run your game from it"
  4. "I want to run it on CD-ROM so it doesn't consume disk space"
  5. "I want to put it on a shared partition so I can use it on any computer"
  6. "I want to put it on a live CD distribution"
  7. "I'm putting together the XXX Linux distro and our policy is not to put games there" (where 'XXX' is both RedHat and SuSE on different occasions).
  8. "I want to put it there - that's how I organise my system and it's none of your damn business how I set up my computer"

So you truly cannot dictate to your end users where they must put the files...not gonna happen - forget it. So FHS (and earlier standards) simply don't help here. Whilst we can ENCOURAGE people to put games in the 'right' places - we cannot force them to do so.

Furthermore, while I (or someone else) is developing the game, we may want half a dozen different versions on the same computer - you certainly don't want them picking up data files from each other's directories! With OpenSourced games, the distinction between 'developer' and 'end user' is at best a blurry one.

My solution

Keep all of your game assets (sources, binaries, libraries, scripts, shaders, data files...everything) in a single directory tree named something pretty unique - I'll use 'mygame' throughout this explanation. This is the way you developed your game (I hope!) - and you'll have done most of your testing in that kind of setup too.

When the user installs the game, provide a small installer script that asks him where he'd like to put the game - with the default being the 'right' place according to FHS.

  Where would you like the game to be installed [/usr/local/mygame] ?

Now your installer knows the place where it's installed. It can write a simple shell script that says:

  export MYGAME_DIRECTORY="...whatever the user entered..."

That script should be written to someplace on the users' PATH that we have write access to. Make a list of likely places (/bin, /usr/bin, /usr/local/bin, /usr/share/bin, etc) - note the ones the script doesn't have write access to - then offer those that survive as default choices to the user.

 Where would you like the 'mygame' startup script to be placed?
 1) /bin/mygame  (requires that you re-run this installer as 'root')
 2) /usr/bin/mygame
 3) /usr/local/bin/mygame
 4) ~/bin/mygame
 5) somewhere else
 Please enter a number 1 through 5 :

Issue a warning if the path he chooses is not on his $PATH right now.

Once that is done, the user runs the script to start the game, and the game itself can note where the current working directory is - and then do a 'chdir(getenv("MYGAME_DIRECTORY"));' and have all of it's files precisely where they were during development. It's worth having it say that if the 'MYGAME_DIRECTORY' shell variable has not been set then set it to ".".

How Commercial Games Do It

Pretty much as I've described above.

Note this screenshot from the Unreal Tournament for Linux installer:


Other advantages

This approach has some major advantages:

  • A convenient installer is less intimidating for your end users.
  • The installer can pull the files from your web server so you can be sure he gets the right versions.
  • If the game runs at all - it has all of the files it needs for sure.
  • You can have the startup script parse command line options like 'uninstall' - which only has to do a simple recursive delete of $MYGAME_DIRECTORY - then delete itself. If it can't find itself then you only left a 100 byte script lying around which is not the end of the world.
  • The startup script can also check that the game is truly installed in $MYGAME_DIRECTORY and provide intelligent diagnostics if it's not.
  • The instructions for developers are now very simple - just run './mygame' from the development directory. Since 'MYGAME_DIRECTORY' will be unset, the game executable will default it to "." and all will be well - no matter how many versions of the game are installed.
  • It's very easy to have the installer do fancy things like make sure that old versions of the game are correctly cleaned up by trying to run 'mygame uninstall' before doing the installation.