Setting up Moonlight and Sunshine to Stream to Steamdeck

An exploration of the configuration of sunshine on a gaming rig to stream to a steamdeck moonlight client.

The Problem

While Steam streaming and Sunshine are both pretty straight forward to configure if you don’t ask much from them, getting them to play nice with a 3 screen computer setup is a relatively poor experience. This is doubly true if the main screen in use is an ultra-wide as these tools do not change the aspect ratio or screen behaviors when streaming out of the box. So when you have a screen setup that looks like a Tie Fighter it is a less than ideal experience between sunshine and moonlight. Lets solve that!

The Goal

When you initiate a connection to sunshine from moonlight on the steamdeck the system should automatically configure the windows PC. This includes disabling secondary displays and adjusting the resolution to match the steamdeck. When the moonlight connection is terminated, roll back these changes and restore the screens to their default resolution and state.

Prereqs

There’s a few things we are going to take for granted here to start.

  • You (the reader) have an up to date copy of sunshine installed on your desktop of choice. The basics of this are covered in the sunshine docs.
  • You have a copy of moonlight installed and configured as a tile on your steamdeck. This is covered extensively in blog posts and YouTube videos the world over, this was the first google hit for me and looks to be a solid explanation.
  • A copy of NirSoft’s Multi-Monitor Tool. This should be placed somewhere you can easily locate and reliably find. I put it inside a folder simply labeled ‘programs’ in my home directory.
  • A piece of software you want to make work by streaming to your steamdeck, I’ll be using Playnite as it lets me aggregate all my desktop game stores into one library interface.

Details to have in front of you before you start

  • Full drive path to your program folder, for example: C:\Users\<username>\Programs\
  • Additionally make note of where MultiMonitorTool is, ie: C:\Users\<username>\Programs\multimonitortool-x64\
  • How many monitors you have, for example: 3
  • The full path to the executable you want to run, for example for Playnite: C:\Users\<username>\AppData\Local\Playnite\Playnite.Fullscreenapp.exe
  • The working directory you want the program to run in, some applications don’t care but Playnite does so: C:\Users\<username>\AppData\Local\Playnite\

HowTo

The basic gist of this is that we are going to use MultiMonitorTool to capture our default configuration, and then the configuration we want for when things are streamed out to the steam deck as configuration files. Once these are captured we’ll use a set of batch scripts to swap the two modes back and forth automatically. You could make this more robust using a proper scripting language like powershell or python but for our purposes here a brute force batch file is sufficient.

Capture Monitor Configurations

To get started, in the windows display settings configure your screens as you would like them to be by default. After this is set start up the MultiMonitorTool GUI and you’ll see a window similar to below.

MultiMonitorTool All Screens Enabled

Once everything is configured as desired, simply go to the File menu button and select Save Monitors Configuration. Place this file somewhere easily located and named something sensible. In my case I chose to simply put this in the folder for MultiMonitorTool and name it default.cfg as this makes the scripts below easier.

After this is complete, reconfigure the screens to be setup as you would like them to be for the Steamdeck or other streaming target. For the Steamdeck, the native resolution is 1280x800; so I’ve disabled the right and left screens on my system and set the primary screens resolution to 1280x800.

Once this is complete, check that the changes are reflected in MultiMonitorTool’s GUI (as below) and save this new configuration in the same place as the first. I named this file simply steamdeck-native.cfg so it’s easy to find.

MultiMonitorTool Steamdeck Native Config

Start Script

This start-up script is invoked before launching the Playnite executable, you’ll need to make a copy of the script below on your local machine. This can be as simply as copying this and pasting it into notepad. This script will turn off your secondary screens and force the resolution settings expected to the primary monitor by invoking the related config file.

Note: You will need to update the cd entry to where your MultiMonitorTool executable is located.

sd-native.bat:

:: disable secondary monitors and switch main monitor to steamdeck native resolution
::
@ECHO OFF
:: update working directory to location of multi monitor tool software.
cd C:\Users\<username>\Programs\multimonitortool-x64
:: toggle off secondary displays; if you have more than 3 displays,
:: add additional display indexes below to turn off all screens except the primary.
.\MultiMonitorTool.exe /disable 2 3
:: load steamdeck compatible configuration file, if you used a different file name
:: you will need to use that config file name here.
.\MultiMonitorTool.exe /LoadConfig ./steamdeck-native.cfg
:: these changes tend to take a few seconds and we don't want anything to launch before hand
:: so just a quick pause so it doesn't launch while things are changing.
timeout /t 2

Exit Script

This script is functionally the inversion of the above script and is meant to run when exiting a sunshine application. This will forcibly restore the default screen configuration but has some subtleties to be aware of. The /LoadConfig flag seems to have some issues with restoring several screens at once, however it can simply be run multiple times to force the system to enable all screens. As such you will need to include the line .\MultiMonitorTool.exe /LoadConfig ./default.cfg once for each monitor you need to re-activate.

Note: As above you will need to update the cd command to the appropriate location for your system.

default-monitor-config.bat

::reset the monitor configuration to default
::
@ECHO OFF
:: update working directory to location of multi monitor tool software.
cd C:\Users\<username>\Programs\multimonitortool-x64
:: re-assert default screen configuration
.\MultiMonitorTool.exe /LoadConfig ./default.cfg
.\MultiMonitorTool.exe /LoadConfig ./default.cfg

Putting it Together in an Sunshine Application Entry

To get started I would make a new application entry in Sunshine for this. While it’s theoretically possible to make these scripts adapt to using the ENVVAR values supplied at the bottom of the application page that’s out of scope for this discussion. Naming the new application entry something that makes it clear it’s a SteamDeck config will help make things obvious on the client side. I went with simply Playnite - SD.

In this new application entry add the full path to your sd-native.bat file to the first entry in the Do Command column. In the neighboring column under Undo Command place the full path to the default-monitor-config.bat file.

For Playnite specifically it’s a good idea to add two additional Undo Command entries of taskkill /f /im Playnite.DesktopApp.exe and taskkill /f /im Playnite.FullscreenApp.exe. Adding these ensures terminating the application entry also kills Playnite.

Under the Command entry further down the page you will need to add the path to Playnite’s main executable, this is typically C:\Users\<username>\AppData\Local\Playnite\Playnite.FullscreenApp.exe, and you’ll want to set the entry Working Directory to simply C:\Users\<username>\AppData\Local\Playnite\.

At this point you are done, the setup should be ready to test out and stream from.

Areas Of Improvement

  • Currently if something goes pear shaped killing the Playnite session will not terminate the underlying application that was launched by it; I’m currently not sure how to do this but will add an article if I come up with a solution. It’s possible using alternative shutdown commands this can be resolved, this will require more experimentation.
  • The script for turning off secondary monitors can fail if the systems graphics drivers have been updated but the system has not been rebooted; the most direct work around is to simply reboot after these kinds of updates.

Read more:

Related posts: