## Adding a game to `game-data-packager`

### Step 0: working with the git tree

    $ git clone https://salsa.debian.org/games-team/game-data-packager.git
    $ meson setup out \
        --prefix=/usr \
        --sysconfdir=/etc \
        --libdir=lib \
        --bindir=games \
        -Dgamedatadir=share/games
    $ meson compile -C out
    $ meson test -C out

(This assumes a Debian-style directory layout, remove the --bindir and
-Dgamedatadir options for non-Debian-derived OSs like Fedora)

Then the `out/run-gdp-uninstalled` command can be used instead of the
system-installed `game-data-packager` command, for example:

    $ out/run-gdp-uninstalled -d ~/tmp/gdp -n zork

Further calls to `meson compile -C out` will only process modified
new game description data in `data/`.

The `out/run-tool-uninstalled` command can be used to run ancillary
tools like `tools/check_steam.py`.

For historical reasons, some scripts assume that the build directory is
named `out` if they are run directly.

### Step 1: locate and describe the necessary files

Write a YAML document that describes the files needed and how to get them.

There are three main constructs in the YAML document: *top-level metadata*,
*known files* and *packages*.

Alternatively, you can try `game-data-packager make-template <directory>`
which should get you easily started.

#### Top-level metadata

* `shortname`: string: the short name of the game, such as `quake3`.
* `longname`: string: the "marketing name" of the game, such as Quake
  III Arena.
* `copyright`: string: © <year_of_first_release> <developper/publisher>
  This should match the title screen of the game, if any.
* `engine`: string: package name that contain the program needed to run the game.
* `genre`: the game genre
* `compression`: boolean or list of strings, default true. If false, the
  `.deb` or `.rpm` will never be compressed. If a list of strings,
  they are dpkg-deb arguments to compress with non-default settings.
  Use this if it contains non-compressible files (e.g. `*.pk3`
  which are zip files) for which `xz` will waste a lot of time and
  produce poor results.
* `try_repack_from`: string or list of strings: extra locations to search
  for data files, in addition to the installed location of the .deb
  and likely Steam directories.
* `help_text`: multi-line hard-wrapped string: extra text for `--help`,
  explaining which files are needed and where to get them.

#### Known files

Known files are identified by a unique name. It is usually the canonical
filename, but if there are several variants of a file (e.g. `doom.wad`)
you must use a distinct name for each variant, for example `doom.wad?1.666`
and `doom.wad?1.9`.

The `?` character in filenames is special: we use it to represent variant
versions of the same file, and by default we remove the `?` and everything
after it when choosing the name to use when the file is installed. For
example, `doom.wad?1.666` gets installed as `doom.wad`.

Known files are described in the `files` top-level item, which is
a mapping from unique name to a mapping:

* `size`: integer: size in bytes
* `distinctive_size`: boolean, default false: if true, files of size `size`
  are assumed to be this file. Use this for large files with a characteristic
  size.
* `distinctive_name`: boolean, default true: if false, files whose name
  matches this file's `look_for` names, but which do not match this file
  by size or hashes, do not provoke a warning. Use this for files with
  generic names like `README.TXT`.
* `license`: boolean, default false: if true, it is listed as a license
  file in generated copyright file.
  Per policy, license files should go in $pkglicensedir. (see `install_to`).
* `download`: string or mapping: where to download this file. FIXME: explain
* `provides`: list of strings: unique names of some known files that can be
  unpacked or extracted from this one
* `md5`: string: md5sum of this file
* `sha1`: string: sha1sum of this file
* `sha256`: string: sha256sum of this file
* `unpack`: mapping: how to unpack this file. The mapping must have at least
  one key, `format`, with possible values currently `tar.gz`, `zip`, `lha`
  or `dos2unix`.
* `alternatives`: list of strings: if given, this known file entry
  is actually an abstraction representing a list of possible known files
  identified by their unique names. Use this if more than one version is
  acceptable, and it is not easy to obtain the most preferred version.
  Alternative sets may not have sizes or checksums, but they may be
  installed in packages, which will result in the first available option
  being installed under the name of the alternative set.
* `install_as`: string: when installing this file in a package, use this name
  instead of its own. The default is to remove the variant marker, if any
  (`?` followed by anything).
* `install_to`: string: overide location where to install this file.
  The special value $pkgdocdir will be expanded to
  usr/share/doc/<package_name>, and $pkglicensedir will be expanded to
  usr/share/doc/<package_name> or usr/share/licenses/<package_name>
  depending on distribution.
* `look_for`: list of strings: when searching for this file, look for
  these names (case-insensitively). The default is a list containing only
  the unique name.

`sha1sums`, `sha256sums` items at top level can be used to provide
the hashes for a bunch of files at the same time.

The `install_files` item in a package (see below) can be used to flag
several files for installation and also provide their metadata
in the same format as `files`.

#### Packages

The `packages` top-level item is a mapping from Debian binary package name
to mapping:

* `longname`: string: the "marketing name" of the game or expansion
  in this package. The default is to use the top-level `longname`,
  with appending ` (demo)` appended for packages with a `demo_for` tag.
* `copyright`: string: the copyright string, if it differs from top-level
* `demo_for`: this reference the full game included in same YAML file
* `expansion_for`: this reference the matching full game included
  in the same YAML file.
  Full games are what you expect.
  Demos are cut-down versions of a full game,
  typically advertised as demo or shareware, which can be installed
  if the full game is not available. Expansions are add-ons or mission
  packs which require the corresponding full game, such as
  Quake III Team Arena for Quake III Arena.
* `install`: list of strings: unique names of known files or alternative
  sets to install
* `engine`: let you overide the engine in special cases
* `activated_by`: Some expansions are free-to-download, but not all users
  will want them. List their most important/distinctive/large files here,
  and the expansion will only be downloaded if game-data-packager finds
  those files or if the user specifically asks for it.

#### Steam games

For games that can be bought from Steam, the top-level metadata, the
individual packages or both can have a mapping named `steam`, with
these keys:

* `id`: the numeric identifier of the game, as seen in
  URLs like http://store.steampowered.com/app/2280/
* `path`: the directory below `steamapps` where Steam installs the game,
  usually starting with `common/`

#### GOG games

Similar to Steam, games sold on gog.com can have a mapping named `gog`
with these keys:

* `url`: the game-specific part of games' URLs, such as
  `the_ultimate_doom` for https://www.gog.com/game/the_ultimate_doom
* `game`: some games are sold on gog.com as a bundle, this is the
  name of each individual part. Use `lgogdownloader --list` to
  know this value. If not specified, this default to the value of `url`.
  Example: `the_zork_anthology` includes `zork_the_great_underground_empire`,
  `zork_ii_the_wizard_of_frobozz`, `zork_iii_the_dungeon_master` ...
* `pp`: an affiliate ID, typically used to donate to a relevant game engine
  (if not specified, g-d-p will use ScummVM's affiliate ID)
* `path`: the directory below `GOG Games` where the GOG installer puts
  the game by default, or a list of strings if more than one directory
  is used by different installer versions. game-data-packager will
  search any directory that starts with this string, so language
  suffixes are not necessary: if GOG will install "Some Game (German)",
  only "Some Game" is needed.

#### Origin games

Similar to Steam, games sold on Origin can have a mapping named `origin`
with these keys:

* `path`: the directory below `Origin Games` where Origin installs the game

Use the `url_misc` top-level key for Origin download URLs: see
`data/syndicate.yaml` and `data/theme-hospital.yaml` for examples.

### Step 2: required files for the `.deb`

#### things to include in the template package

Debian policy requires the following to be present within the metadata
section of a binary package

 * the control file
 * a copyright file, in `/usr/share/doc/package/copyright`

`game-data-packager` will automatically build the copyright file
using the contents of the `copyright:` tags in the yaml file;
you only need to provide one if the default generated
copyright file isn't suitable; see for example
`data/descent1-demo-data.copyright`.

`game-data-packager` will automatically build the control file.
It will also ensure that all the field required by policy
are present:

 * `Version` field. This will automatically be filled with
   the version of gdp which generated the template package.
   If the generated package is guaranteed to contain the vendor's
   version 1.23 data, you may set it in the `debian: version:`
   of the YAML file.
 * `Maintainer`.  We recommend using the same maintainer as for gdp,
   which is the Debian Games Team. This is also the default value that
   will be provided if this field is missing.
 * `Description`. Both the single line synopsis and the extended
   description that follows.
   Most of the extended description is automatically edited,
   you can provide extra information by using a `description:` tag.
 * Any required dependencies.  For game data packages, we use
   `Recommends` to recommend a corresponding engine package, where
   appropriate. To document an engine, you should add
   a `engine:` key in the YAML file.
   If your game is split in several packages, the package with
   the full game should have a `Suggests` relationship on all the available
   expansions; to avoid them being classified as unused
   and then removed by aptitude or deborphan. This is done
   automatically if you set the correct `expansion_for:`.
   An expansion will also automatically have a `Depends` relationship with
   the matching full game.
   If ever needed; the standard Debian dependencies are also supported
   using the `debian: depends:/recommends:/suggests:/replaces:/...` keys.

`game-data-packager` also automatically adds:

 * `md5sums` file, so that the user can check whether a package's installed
   files have been modified if they so desire
 * a copy of gdp's own `changelog`

Finally, it might be worth considering the following

 * Should the data package register any menus, or carry a `.desktop` file?
   In some cases, it makes sense to do this from the data package, rather
   than from the engine package.
   * you may also wish to provide an icon file, but bear in mind that if
     you distribute the icon file inside gdp's source, it needs to meet
     the DFSG.  gdp could generate the icon file at run-time in some
     cases.

### Step 3: include the game in the build

Add the name of your game to the `data/meson.build` file.  game-data-packager
will attempt to read game data packaging information from `data/<name>.yaml`.

### Step 4: advanced

You can write a Python plugin in `game_data_packager/games/SHORTNAME.py`
if you need to implement different command-line parsing or behaviour.
Please don't do this unless you really need to.

If you're adding a scummvm game, this list will help you find out
which version you have, but it only includes md5sum of
the N-th first bytes of the main data file:
https://github.com/scummvm/scummvm/blob/master/devtools/scumm-md5.txt
