Contributing to steamrt
=======================

Issue tracking
--------------

Our main bug tracking system for the whole Steam Runtime is
<https://github.com/ValveSoftware/steam-runtime/issues>. Before reporting
an issue, please take a look at the
[bug reporting information](https://github.com/ValveSoftware/steam-runtime/blob/HEAD/doc/reporting-steamlinuxruntime-bugs.md)
to make sure your issue report contains all the information we need.

The issue tracker on our Gitlab installation, `gitlab.steamos.cloud`, is
primarily used internally by Steam Runtime developers to track issues for
which we already know the technical details of what is happening.

Contributing code
-----------------

At the moment our Gitlab installation, `gitlab.steamos.cloud`, is not
set up to receive merge requests from third-party contributors. However,
git is a distributed version control system, so it is possible to push a
clone of the steamrt git repository to some other git hosting platform
(such as Github or `gitlab.com`) and send a link to a proposed branch
via an issue report.

If you want to contribute code to steamrt, please include a
`Signed-off-by` message in your commits to indicate acceptance of the
[Developer's Certificate of Origin](https://developercertificate.org/)
terms.

Common tasks
============

Adding a library to the SDK
---------------------------

Suppose you want to add `libfoo-dev` to the SDK.

Install `libfoo-dev` in a `sniper` container/chroot, and check what other
packages it pulls in, and where they came from (`sniper` or `bullseye`).
Check that those packages have acceptable licensing terms.

Check whether you can install `libfoo-dev:amd64` and `libfoo-dev:i386`
in a `sniper` container/chroot without needing to remove anything else.

Edit `debian/control` and add `libfoo-dev` to an appropriate `Depends`
list. If you can co-install the amd64 and i386 versions of it, add it
to `steamrt-libdevel`. If not, add it to `steamrt-libdevel-non-multiarch`.

If you want to be able to ship games that use this library unconditionally,
you'll need to provide the library in the runtime (see below).

Adding a library to the Platform
--------------------------------

Suppose you want to add `libFoo.so.1` to the runtime.

Install `libfoo1` (or whatever is the right package name) in a `sniper`
container/chroot, and check what other packages it pulls in, and where
they came from (`sniper` or `bullseye`).  Check that those packages have
acceptable licensing terms.

Check whether you can install `libfoo1:amd64` and `libfoo1:i386`
in a `sniper` container/chroot without needing to remove anything else.
If you can't, improve the packaging until you can (install to Multi-Arch
directories and set `Multi-Arch: same`). We don't support libraries that
are not multi-arch co-installable.

Edit `abi/steam-runtime-abi.yaml` and add the new library and each of its
(recursive) dependencies. If the name of the package matches the SONAME,
you can just add it to the list as a string, similar to `libX11.so.6`. If
not, you'll have to add it as a dict that contains a `deb:` key, similar
to `libz.so.1` containing `deb: zlib1g`.

After editing `abi/steam-runtime-abi.yaml`, regenerate
the `abi/expectations` directory by running
`abi/maintainer-generate-expectations.py` in a `sniper` chroot or container.

If you want to be able to compile against this library without downloading
extra packages, you'll need to provide the library in the SDK (see above).

Testing a new sniper runtime
----------------------------

### Within Steam, for games

Build the runtime using CI or `flatdeb-steam`.
Various artifacts are produced, but the one we need here is
either `SteamLinuxRuntime_sniper.tar.xz` or
`com.valvesoftware.SteamRuntime.Platform-amd64,i386-sniper-runtime.tar.gz`.

If you have downloaded `SteamLinuxRuntime_sniper.tar.xz`, you can replace
the entire `steamapps/common/SteamLinuxRuntime_sniper` directory:

```
$ common=/path/to/steamapps/common
$ rm -fr "$common"/SteamLinuxRuntime_sniper
$ tar -C "$common" -xf SteamLinuxRuntime_sniper.tar.xz
```

This will replace everything in the SLR directory, including pressure-vessel.

Or if you only downloaded
`com.valvesoftware.SteamRuntime.Platform-amd64,i386-sniper-runtime.tar.gz`,
you can modify an existing copy of SLR to use it, keeping the existing
pressure-vessel and helper scripts:

```
$ common=/path/to/steamapps/common
$ rm -fr "$common"/SteamLinuxRuntime_sniper/sniper_test
$ mkdir "$common"/SteamLinuxRuntime_sniper/sniper_test
$ tar -C "$common"/SteamLinuxRuntime_sniper/sniper_test \
    -xf com.valvesoftware.SteamRuntime.Platform-amd64,i386-sniper-runtime.tar.gz
$ sed -i -e 's,^dir=,dir=sniper_test,' "$common"/SteamLinuxRuntime_sniper/run
$ sed -i -e 's,^dir=,dir=sniper_test,' "$common"/SteamLinuxRuntime_sniper/run-in-sniper
```

You can use multiple subdirectories of `SteamLinuxRuntime_sniper`
to keep different runtime versions available, but for compatibility
with old versions of the runtime, their names cannot start with either
`sniper_0.` or `sniper_before_`.  A name starting with `sniper_test`
or `sniper_platform` is recommended.

There are currently two interesting use-cases for sniper games:

* Configure a Windows game to use the `Proton Experimental`
    compatibility tool, or Proton version 8 or newer (or run a
    Windows-only game that uses one of these Proton versions by default).
    These Proton versions run in a `sniper` container.

* Launch a game that was developed against sniper, such as
    Counter-Strike 2, Dota 2 or Retroarch.

In both cases, it can be useful to launch Steam with the environment
variable `PRESSURE_VESSEL_SHELL=instead`, or set the game's launch options
to `PRESSURE_VESSEL_SHELL=instead %command%`. This provides an easy way to
confirm that you are using the runtime you think you are using: its version
number appears in the shell prompt. Type `"$@"` to run the game.

It is often also useful to set the game's Launch Options to:

```
steam-runtime-launch-options -- %command%
```

### Within Steam, for `steamwebhelper`

This use-case is not yet documented here.

### Outside Steam

Build the runtime using CI or `flatdeb-steam`, as before.
Various artifacts are produced, but the only one we need here is
`com.valvesoftware.SteamRuntime.Platform-amd64,i386-sniper-runtime.tar.gz`.

Unpack it into an empty directory, for example `~/tmp/sniper`, so that
you have `~/tmp/sniper/metadata` and `~/tmp/sniper/files/bin/env`.
Create a directory on the same filesystem that can be used for temporary
copies and logs, for example `~/tmp/pressure-vessel-var`.

Download a pressure-vessel relocatable release from
<https://repo.steampowered.com/pressure-vessel/snapshots/> and unpack it
into a directory, or use the one included in `SteamLinuxRuntime_sniper`,
or build your own.

Then run a command like:

```
$ .../pressure-vessel/bin/pressure-vessel-wrap \
    --variable-dir ~/tmp/pressure-vessel-var \
    --copy-runtime \
    --runtime ~/tmp/sniper \
    -- \
    xterm
```

Testing a new sniper SDK
------------------------

Build the runtime using CI or `flatdeb-steam`. Various artifacts are
produced, but the ones we'll need here are
`com.valvesoftware.SteamRuntime.Sdk-amd64,i386-sniper-sysroot.tar.gz`
and `com.valvesoftware.SteamRuntime.Sdk-amd64,i386-sniper-sysroot.Dockerfile`.
Download them into a new, empty directory and `cd` into that directory.

For Docker users:

    $ sudo docker build -t steamrt_sniper_amd64:latest -f *.Dockerfile .

Then you can use the `steamrt_sniper_amd64` Docker image for builds.

For Podman users: it's the same as Docker, but use `podman build` instead
of `sudo docker build`.

For `schroot` users:

    $ /path/to/steam-runtime/setup_chroot.sh --suite=sniper --amd64 --tarball *-sysroot.tar.gz
