diff --git a/pressure-vessel/flatpak-run-private.h b/pressure-vessel/flatpak-run-private.h
index 67b5cc0adfae025f95182d99dc79fd158ffd3b8e..f128f00c327c3f533d2cac6dff7d9bd59df024eb 100644
--- a/pressure-vessel/flatpak-run-private.h
+++ b/pressure-vessel/flatpak-run-private.h
@@ -38,6 +38,12 @@
 #include "flatpak-utils-private.h"
 #include "steam-runtime-tools/glib-backports-internal.h"
 
+/* modified for pressure-vessel */
+gboolean flatpak_run_in_transient_unit (const char *owner,
+                                        const char *prefix,
+                                        const char *appid,
+                                        GError    **error);
+
 /* See flatpak-metadata(5) */
 
 #define FLATPAK_METADATA_GROUP_APPLICATION "Application"
diff --git a/pressure-vessel/flatpak-run.c b/pressure-vessel/flatpak-run.c
index a43babb7b9544f70c5f980e7670837406f2eca0f..32b07ae19195e9591cc15bffea74765139fa09e4 100644
--- a/pressure-vessel/flatpak-run.c
+++ b/pressure-vessel/flatpak-run.c
@@ -48,6 +48,7 @@
 
 #include "flatpak-utils-base-private.h"
 #include "flatpak-utils-private.h"
+#include "flatpak-systemd-dbus-generated.h"
 
 /* In Flatpak this is optional, in pressure-vessel not so much */
 #define ENABLE_XAUTH
@@ -1673,6 +1674,8 @@ flatpak_ensure_data_dir (GFile        *app_id_dir,
   return TRUE;
 }
 
+#endif
+
 struct JobData
 {
   char      *job;
@@ -1707,8 +1710,16 @@ systemd_unit_name_escape (const gchar *in)
   return g_string_free (str, FALSE);
 }
 
+/*
+ * Modified from Flatpak's version. For simplicity we assume that @owner
+ * and @prefix are in a form that don't need escaping to be a valid systemd
+ * scope name.
+ */
 gboolean
-flatpak_run_in_transient_unit (const char *appid, GError **error)
+flatpak_run_in_transient_unit (const char *owner,
+                               const char *prefix,
+                               const char *appid,
+                               GError **error)
 {
   g_autoptr(GDBusConnection) conn = NULL;
   g_autofree char *path = NULL;
@@ -1753,7 +1764,8 @@ flatpak_run_in_transient_unit (const char *appid, GError **error)
     goto out;
 
   appid_escaped = systemd_unit_name_escape (appid);
-  name = g_strdup_printf ("app-flatpak-%s-%d.scope", appid_escaped, getpid ());
+  name = g_strdup_printf ("app-%s-%s%s-%d.scope",
+                          owner, prefix, appid_escaped, getpid ());
 
   g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sv)"));
 
@@ -1795,8 +1807,6 @@ out:
   return res;
 }
 
-#endif
-
 void
 flatpak_run_add_font_path_args (FlatpakBwrap *bwrap)
 {
diff --git a/pressure-vessel/wrap-setup.c b/pressure-vessel/wrap-setup.c
index 98f48ab05f1bf9b5594395db2b360a720bd4f57e..b381bdbe8a1438f589bc4cd20485c2b8631fb3be 100644
--- a/pressure-vessel/wrap-setup.c
+++ b/pressure-vessel/wrap-setup.c
@@ -287,3 +287,46 @@ pv_wrap_use_host_os (FlatpakExports *exports,
 
   return TRUE;
 }
+
+const char *
+pv_wrap_get_steam_app_id (const char *from_command_line)
+{
+  const char *value;
+
+  if (from_command_line != NULL)
+    return from_command_line;
+
+  if ((value = g_getenv ("STEAM_COMPAT_APP_ID")) != NULL)
+    return value;
+
+  if ((value = g_getenv ("SteamAppId")) != NULL)
+    return value;
+
+  return NULL;
+}
+
+/*
+ * Try to move the current process into a scope defined by the given
+ * Steam app ID. If that's not possible, ignore.
+ */
+void
+pv_wrap_move_into_scope (const char *steam_app_id)
+{
+  g_autoptr(GError) local_error = NULL;
+
+  if (steam_app_id != NULL)
+    {
+      if (steam_app_id[0] == '\0')
+        steam_app_id = NULL;
+      else if (strcmp (steam_app_id, "0") == 0)
+        steam_app_id = NULL;
+    }
+
+  if (steam_app_id != NULL)
+    flatpak_run_in_transient_unit ("steam", "app", steam_app_id, &local_error);
+  else
+    flatpak_run_in_transient_unit ("steam", "", "unknown", &local_error);
+
+  if (local_error != NULL)
+    g_debug ("Cannot move into a systemd scope: %s", local_error->message);
+}
diff --git a/pressure-vessel/wrap-setup.h b/pressure-vessel/wrap-setup.h
index aae933076e390fc80124c26236b6d0300d5003ea..cfeef954a5360116cee4cac94eac54ea1287aa2c 100644
--- a/pressure-vessel/wrap-setup.h
+++ b/pressure-vessel/wrap-setup.h
@@ -36,3 +36,7 @@ void pv_wrap_share_sockets (FlatpakBwrap *bwrap,
 gboolean pv_wrap_use_host_os (FlatpakExports *exports,
                               FlatpakBwrap *bwrap,
                               GError **error);
+
+void pv_wrap_move_into_scope (const char *steam_app_id);
+
+const char *pv_wrap_get_steam_app_id (const char *from_command_line);
diff --git a/pressure-vessel/wrap.c b/pressure-vessel/wrap.c
index 2bcb3d5df2f3bad20ea463d2358241e7c0864acc..d2b352f0d3b148795e9a5a0bb3e40e7d18a4c8d9 100644
--- a/pressure-vessel/wrap.c
+++ b/pressure-vessel/wrap.c
@@ -703,6 +703,7 @@ static char *opt_runtime_id = NULL;
 static Tristate opt_share_home = TRISTATE_MAYBE;
 static gboolean opt_share_pid = TRUE;
 static gboolean opt_single_thread = FALSE;
+static gboolean opt_systemd_scope = FALSE;
 static double opt_terminate_idle_timeout = 0.0;
 static double opt_terminate_timeout = -1.0;
 static char *opt_variable_dir = NULL;
@@ -1222,6 +1223,12 @@ static GOptionEntry options[] =
     G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_single_thread,
     "Disable multi-threaded code paths, for debugging",
     NULL },
+  { "systemd-scope", '\0',
+    G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_systemd_scope,
+    "Attempt to run the game in a systemd scope", NULL },
+  { "no-systemd-scope", '\0',
+    G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_systemd_scope,
+    "Do not run the game in a systemd scope", NULL },
   { "terminal", '\0',
     G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, opt_terminal_cb,
     "none: disable features that would use a terminal; "
@@ -1338,6 +1345,7 @@ main (int argc,
   g_autoptr(PvRuntime) runtime = NULL;
   g_autoptr(FILE) original_stdout = NULL;
   g_autoptr(GArray) pass_fds_through_adverb = g_array_new (FALSE, FALSE, sizeof (int));
+  const char *steam_app_id;
 
   setlocale (LC_ALL, "");
 
@@ -1399,6 +1407,8 @@ main (int argc,
 
   opt_remove_game_overlay = pv_boolean_environment ("PRESSURE_VESSEL_REMOVE_GAME_OVERLAY",
                                                     FALSE);
+  opt_systemd_scope = pv_boolean_environment ("PRESSURE_VESSEL_SYSTEMD_SCOPE",
+                                              opt_systemd_scope);
   opt_import_vulkan_layers = pv_boolean_environment ("PRESSURE_VESSEL_IMPORT_VULKAN_LAYERS",
                                                      TRUE);
 
@@ -1577,6 +1587,8 @@ main (int argc,
       argc--;
     }
 
+  steam_app_id = pv_wrap_get_steam_app_id (opt_steam_app_id);
+
   home = g_get_home_dir ();
 
   if (opt_share_home == TRISTATE_YES)
@@ -1598,27 +1610,11 @@ main (int argc,
       opt_fake_home = g_build_filename (home, ".var", "app",
                                         opt_freedesktop_app_id, NULL);
     }
-  else if (opt_steam_app_id)
-    {
-      is_home_shared = FALSE;
-      opt_freedesktop_app_id = g_strdup_printf ("com.steampowered.App%s",
-                                                opt_steam_app_id);
-      opt_fake_home = g_build_filename (home, ".var", "app",
-                                        opt_freedesktop_app_id, NULL);
-    }
-  else if (g_getenv ("STEAM_COMPAT_APP_ID") != NULL)
-    {
-      is_home_shared = FALSE;
-      opt_freedesktop_app_id = g_strdup_printf ("com.steampowered.App%s",
-                                                g_getenv ("STEAM_COMPAT_APP_ID"));
-      opt_fake_home = g_build_filename (home, ".var", "app",
-                                        opt_freedesktop_app_id, NULL);
-    }
-  else if (g_getenv ("SteamAppId") != NULL)
+  else if (steam_app_id != NULL)
     {
       is_home_shared = FALSE;
       opt_freedesktop_app_id = g_strdup_printf ("com.steampowered.App%s",
-                                                g_getenv ("SteamAppId"));
+                                                steam_app_id);
       opt_fake_home = g_build_filename (home, ".var", "app",
                                         opt_freedesktop_app_id, NULL);
     }
@@ -2787,9 +2783,15 @@ main (int argc,
     }
 
   if (opt_only_prepare)
-    ret = 0;
-  else
-    pv_bwrap_execve (final_argv, fileno (original_stdout), error);
+    {
+      ret = 0;
+      goto out;
+    }
+
+  if (opt_systemd_scope)
+    pv_wrap_move_into_scope (steam_app_id);
+
+  pv_bwrap_execve (final_argv, fileno (original_stdout), error);
 
 out:
   if (local_error != NULL)