diff --git a/docs/steam-compat-tool-interface.md b/docs/steam-compat-tool-interface.md
index 7fb910d69725725b9ca15fb6efe8a1e199dfad23..c7017a06d22f1f9b613049c88c71d4f75b9137f6 100644
--- a/docs/steam-compat-tool-interface.md
+++ b/docs/steam-compat-tool-interface.md
@@ -393,6 +393,14 @@ Some environment variables are set by Steam, including:
     (For example, a game's Launch Options can be set to
     `STEAM_COMPAT_RUNTIME_SDL2=1 %command%`)
 
+    May also be set to `sdl2-compat` to attempt to use the
+    [sdl2-compat][] library, if available, in preference to
+    "classic" SDL2.
+    This will only work if the container runtime actually contains a
+    copy of sdl2-compat.
+    (For example, a game's Launch Options can be set to
+    `STEAM_COMPAT_RUNTIME_SDL2=sdl2-compat %command%`)
+
 * `STEAM_COMPAT_RUNTIME_SDL3`:
 
     May be set to 1 for the same effect as adding `runtime-sdl3` to
@@ -654,5 +662,6 @@ unless this is set to the game's top-level directory.
 [ldlp]: ld-library-path-runtime.md
 [prctl]: https://manpages.debian.org/unstable/manpages-dev/prctl.2.en.html
 [scout-on-soldier]: container-runtime.md#steam-linux-runtime-scout-on-soldier
+[sdl2-compat]: https://github.com/libsdl-org/sdl2-compat/
 [sniper]: container-runtime.md#steam-runtime-3-sniper
 [soldier]: container-runtime.md#steam-runtime-2-soldier
diff --git a/pressure-vessel/adverb-sdl.c b/pressure-vessel/adverb-sdl.c
index 72474c4b687f7f801f00a588ce952cc8fd72e38d..c0d2c2fc4b24f4840cbbb176b68285353119ed18 100644
--- a/pressure-vessel/adverb-sdl.c
+++ b/pressure-vessel/adverb-sdl.c
@@ -6,16 +6,31 @@
 #include "config.h"
 #include "adverb-sdl.h"
 
+/*
+ * pv_adverb_set_up_dynamic_sdl:
+ * @wrapped_command: The command to run and its environment
+ * @lib_temp_dirs (nullable): A set of per-architecture directories
+ *  using the dynamic string tokens `${PLATFORM}` or `${LIB}`
+ * @prefix: Where to find SDL, normally `/usr` unless unit-testing
+ * @overrides: Path to libraries overridden by the #PvRuntime,
+ *  for example `/overrides`
+ * @dynamic_var: Environment variable name such as `SDL_DYNAMIC_API`
+ * @library: Path to SDL relative to `${libdir}`,
+ *  for example `sdl2-compat/libSDL2-2.0.so.0`
+ * @error: Used to report error on failure
+ */
 gboolean
 pv_adverb_set_up_dynamic_sdl (FlatpakBwrap *wrapped_command,
                               PvPerArchDirs *lib_temp_dirs,
                               const char *prefix,
                               const char *overrides,
                               const char *dynamic_var,
-                              const char *soname,
+                              const char *library,
                               GError **error)
 {
   gboolean have_any = FALSE;
+  /* Only the filename part of @library */
+  const char *soname = glnx_basename (library);
   size_t abi_index;
   const char *existing_value;
 
@@ -26,7 +41,7 @@ pv_adverb_set_up_dynamic_sdl (FlatpakBwrap *wrapped_command,
       /* Treat SDL{,3}_DYNAMIC_API from e.g. launch options as being
        * more important than STEAM_COMPAT_FLAGS=runtime-sdl{2,3} */
       g_message ("Not using %s from runtime because %s is already set to \"%s\"",
-                 soname, dynamic_var, existing_value);
+                 library, dynamic_var, existing_value);
       return TRUE;
     }
 
@@ -45,8 +60,8 @@ pv_adverb_set_up_dynamic_sdl (FlatpakBwrap *wrapped_command,
 
       /* We assume a Debian multiarch layout here: in practice this
        * is true for all Steam Runtime branches. */
-      from_runtime = g_build_filename (prefix, "lib", multiarch_tuple, soname, NULL);
-      override = g_build_filename (overrides, "lib", multiarch_tuple, soname, NULL);
+      from_runtime = g_build_filename (prefix, "lib", multiarch_tuple, library, NULL);
+      override = g_build_filename (overrides, "lib", multiarch_tuple, library, NULL);
 
       if (g_file_test (override, G_FILE_TEST_EXISTS))
         {
@@ -57,7 +72,7 @@ pv_adverb_set_up_dynamic_sdl (FlatpakBwrap *wrapped_command,
            * in the graphics stack does depend on SDL, we really have
            * no choice but to use that version. */
           g_message ("Using %s %s from graphics stack provider instead of runtime",
-                     multiarch_tuple, soname);
+                     multiarch_tuple, library);
           target = override;
         }
       else if (g_file_test (from_runtime, G_FILE_TEST_EXISTS))
@@ -88,14 +103,14 @@ pv_adverb_set_up_dynamic_sdl (FlatpakBwrap *wrapped_command,
       g_autofree gchar *value = NULL;
 
       value = g_build_filename (lib_temp_dirs->libdl_token_path, soname, NULL);
-      g_info ("Setting %s=\"%s\" to use runtime's SDL", dynamic_var, soname);
+      g_info ("Setting %s=\"%s\" to use runtime's %s", dynamic_var, soname, library);
       flatpak_bwrap_set_env (wrapped_command, dynamic_var, value, TRUE);
     }
   else
     {
       return glnx_throw (error,
                          "Unable to set %s: %s wasn't available for any architecture",
-                         dynamic_var, soname);
+                         dynamic_var, library);
     }
 
   return TRUE;
@@ -111,11 +126,16 @@ pv_adverb_set_up_dynamic_sdls (FlatpakBwrap *wrapped_command,
   static const struct
     {
       const char *dynamic_var;
-      const char *soname;
+      const char *library;
       SrtSteamCompatFlags if_flag;
     }
   sdls[] =
     {
+        {
+            "SDL_DYNAMIC_API",
+            "sdl2-compat/libSDL2-2.0.so.0",
+            SRT_STEAM_COMPAT_FLAGS_RUNTIME_SDL2_COMPAT
+        },
         {
             "SDL_DYNAMIC_API",
             "libSDL2-2.0.so.0",
@@ -140,7 +160,7 @@ pv_adverb_set_up_dynamic_sdls (FlatpakBwrap *wrapped_command,
                                              prefix,
                                              overrides,
                                              sdls[i].dynamic_var,
-                                             sdls[i].soname,
+                                             sdls[i].library,
                                              &local_error))
             g_warning ("%s", local_error->message);
         }
diff --git a/pressure-vessel/wrap.1.md b/pressure-vessel/wrap.1.md
index 920d9d09ff6d92adefe0abeeff35f1bedc9692da..1f16614c0fa0446d317b68de776270c0fcae92e7 100644
--- a/pressure-vessel/wrap.1.md
+++ b/pressure-vessel/wrap.1.md
@@ -1105,7 +1105,7 @@ be made available read/write in the container.
 </dd>
 <dt>
 
-`STEAM_COMPAT_RUNTIME_SDL2` (boolean)
+`STEAM_COMPAT_RUNTIME_SDL2` (`0`, `1` or `sdl2-compat`)
 
 </dt><dd>
 
@@ -1119,6 +1119,11 @@ paths so that both 32- and 64-bit SDL 2 will work.
 Typically this would be enabled by setting a game's Steam launch
 options to `STEAM_COMPAT_RUNTIME_SDL2=1 %command%`.
 
+If set to `sdl2-compat`,
+and the runtime contains a copy of `sdl2-compat` as a non-default
+implementation of SDL,
+do the same for that.
+
 </dd>
 <dt>
 
diff --git a/steam-runtime-tools/steam-internal.h b/steam-runtime-tools/steam-internal.h
index 9cdf16149d4001ec065faa9d05e41ef13a9c1373..74877413a4e0c3cf5f3b27ca3617815cd5b4ef3e 100644
--- a/steam-runtime-tools/steam-internal.h
+++ b/steam-runtime-tools/steam-internal.h
@@ -80,6 +80,7 @@ typedef enum
   SRT_STEAM_COMPAT_FLAGS_SYSTEM_TRACING = (1 << 2),
   SRT_STEAM_COMPAT_FLAGS_RUNTIME_SDL2 = (1 << 3),
   SRT_STEAM_COMPAT_FLAGS_RUNTIME_SDL3 = (1 << 4),
+  SRT_STEAM_COMPAT_FLAGS_RUNTIME_SDL2_COMPAT = (1 << 5),
   SRT_STEAM_COMPAT_FLAGS_NONE = 0
 } SrtSteamCompatFlags;
 
diff --git a/steam-runtime-tools/steam.c b/steam-runtime-tools/steam.c
index ff9bd7242922124dadb844d3679410c84db266ba..c0f2a92a0da016b8a8f91900ab42ee1906b2500e 100644
--- a/steam-runtime-tools/steam.c
+++ b/steam-runtime-tools/steam.c
@@ -760,7 +760,6 @@ _srt_steam_get_compat_flags (const char * const *envp)
   bool_vars[] =
     {
         { "STEAM_COMPAT_TRACING", SRT_STEAM_COMPAT_FLAGS_SYSTEM_TRACING, FALSE },
-        { "STEAM_COMPAT_RUNTIME_SDL2", SRT_STEAM_COMPAT_FLAGS_RUNTIME_SDL2, FALSE },
         { "STEAM_COMPAT_RUNTIME_SDL3", SRT_STEAM_COMPAT_FLAGS_RUNTIME_SDL3, FALSE },
     };
   SrtSteamCompatFlags ret = SRT_STEAM_COMPAT_FLAGS_NONE;
@@ -777,6 +776,22 @@ _srt_steam_get_compat_flags (const char * const *envp)
         ret |= bool_vars[i].value;
     }
 
+  value = _srt_environ_getenv (envp, "STEAM_COMPAT_RUNTIME_SDL2");
+
+  if (value != NULL)
+    {
+      if (g_strcmp0 (value, "1") == 0)
+        ret |= SRT_STEAM_COMPAT_FLAGS_RUNTIME_SDL2;
+      else if (g_strcmp0 (value, "sdl2-compat") == 0)
+        ret |= SRT_STEAM_COMPAT_FLAGS_RUNTIME_SDL2_COMPAT;
+      else if (value[0] == '\0' || g_strcmp0 (value, "0") == 0)
+        ret &= ~(SRT_STEAM_COMPAT_FLAGS_RUNTIME_SDL2
+                 | SRT_STEAM_COMPAT_FLAGS_RUNTIME_SDL2_COMPAT);
+      else
+        g_warning ("Unrecognised value \"%s\" for $STEAM_COMPAT_RUNTIME_SDL2",
+                   value);
+    }
+
   value = _srt_environ_getenv (envp, "STEAM_COMPAT_FLAGS");
 
   if (value != NULL)
diff --git a/tests/pressure-vessel/adverb-sdl.c b/tests/pressure-vessel/adverb-sdl.c
index 207f3c4b877ff37c9d00a225ab2e6210b91ee9ad..3cbdc5a7e8d655702a4b51f2abef6f220746cad4 100644
--- a/tests/pressure-vessel/adverb-sdl.c
+++ b/tests/pressure-vessel/adverb-sdl.c
@@ -14,6 +14,7 @@
 
 #define SDL_DYNAMIC_API "SDL_DYNAMIC_API"
 #define SDL2_SONAME "libSDL2-2.0.so.0"
+#define SDL2_COMPAT "sdl2-compat/libSDL2-2.0.so.0"
 #define SDL3_DYNAMIC_API "SDL3_DYNAMIC_API"
 #define SDL3_SONAME "libSDL3.so.0"
 
@@ -167,6 +168,8 @@ static void
 test_basic (Fixture *f,
             gconstpointer context)
 {
+  g_autofree gchar *sdl2_compat_target = NULL;
+  g_autofree gchar *sdl2_symlink = NULL;
   g_autofree gchar *sdl2_target = NULL;
   g_autofree gchar *sdl3_target = NULL;
 
@@ -181,6 +184,9 @@ test_basic (Fixture *f,
   touch (&sdl2_target,
          f->mock_prefix.path, "lib", pv_multiarch_tuples[PV_PRIMARY_ARCHITECTURE],
          SDL2_SONAME, NULL);
+  touch (&sdl2_compat_target,
+         f->mock_prefix.path, "lib", pv_multiarch_tuples[PV_PRIMARY_ARCHITECTURE],
+         SDL2_COMPAT, NULL);
   touch (&sdl3_target,
          f->mock_prefix.path, "lib", pv_multiarch_tuples[PV_PRIMARY_ARCHITECTURE],
          SDL3_SONAME, NULL);
@@ -226,6 +232,22 @@ test_basic (Fixture *f,
               f->lib_temp_dirs->libdl_token_path, SDL2_SONAME);
   assert_env (f->bwrap->envp, SDL3_DYNAMIC_API,
               f->lib_temp_dirs->libdl_token_path, SDL3_SONAME);
+
+  flatpak_bwrap_unset_env (f->bwrap, SDL_DYNAMIC_API);
+  sdl2_symlink = g_build_filename (f->lib_temp_dirs->abi_paths[PV_PRIMARY_ARCHITECTURE],
+                                   SDL2_SONAME, NULL);
+  unlink (sdl2_symlink);
+
+  g_test_message ("sdl2-compat flag sets up sdl2-compat...");
+  pv_adverb_set_up_dynamic_sdls (f->bwrap,
+                                 f->lib_temp_dirs,
+                                 f->mock_prefix.path,
+                                 f->mock_overrides.path,
+                                 SRT_STEAM_COMPAT_FLAGS_RUNTIME_SDL2_COMPAT);
+  assert_symlink (f->lib_temp_dirs->abi_paths[PV_PRIMARY_ARCHITECTURE],
+                  SDL2_SONAME, sdl2_compat_target, 0);
+  assert_env (f->bwrap->envp, SDL_DYNAMIC_API,
+              f->lib_temp_dirs->libdl_token_path, SDL2_SONAME);
 }
 
 static void
diff --git a/tests/utils.c b/tests/utils.c
index 8fbb2e9138b5e9fdd02dfff0c6aca8901fe6d713..aa51c66020a4ad111391d59dfffaea8df6ed33f8 100644
--- a/tests/utils.c
+++ b/tests/utils.c
@@ -174,6 +174,10 @@ test_compat_flags (Fixture *f,
         { { "STEAM_COMPAT_TRACING=", NULL }, SRT_STEAM_COMPAT_FLAGS_NONE },
         { { "STEAM_COMPAT_TRACING=0", NULL }, SRT_STEAM_COMPAT_FLAGS_NONE },
         { { "STEAM_COMPAT_RUNTIME_SDL2=1", NULL }, SRT_STEAM_COMPAT_FLAGS_RUNTIME_SDL2 },
+        {
+            { "STEAM_COMPAT_RUNTIME_SDL2=sdl2-compat", NULL },
+            SRT_STEAM_COMPAT_FLAGS_RUNTIME_SDL2_COMPAT,
+        },
         { { "STEAM_COMPAT_RUNTIME_SDL3=1", NULL }, SRT_STEAM_COMPAT_FLAGS_RUNTIME_SDL3 },
         { { NULL }, SRT_STEAM_COMPAT_FLAGS_NONE }
     };