Sunday, August 11, 2024

How to set up a self booting dedicated Moonlight (Sunshine client of Nvidia's GameStream) on a Raspberry Pi 3B+

8/11/2024:  This guide shows you how to set up a Raspberry Pi 3B+ (and older?) to stream your desktop PC from anywhere on your home network to any TV in your house using Gamestream/Sunshine via Moonlight.

I use this so I can run full speed games and full sound applications and full video streaming from my main PC to my various TV's around the house and (shhhhh) to a monitor on KVM on my work from home desk setup.  Basically, these little ancient Pi 3B+'s are more than powerful enough to run full speed 1080p Moonlight.  Especially with wired ethernet.

---------------------------

Disclaimer: I am not an expert.  I'm bad at Linux.  I figured this out reading lots and lots of README's and proper wiki and FAQ's and TONS and TONS of message board posts.  The three main links you need:

https://www.raspberrypi.com/software/ - Bullseye 32 Bit Lite
https://www.raspberrypi.com/documentation/computers/configuration.html - How to use Raspi-Config
https://github.com/moonlight-stream/moonlight-embedded/wiki/Packages - Commandlines to install Moonlight.
https://github.com/moonlight-stream/moonlight-embedded/wiki/Usage - Commands for using moonlight.
https://www.makeuseof.com/what-is-systemd-launch-programs-raspberry-pi/ - Basics on how to set a SYSTEMD service to autoboot.

---------------------------
If you want to speed run this guide and are fluent in Linux/Raspian, try the following shorthand steps.  (HOWEVER, I have no idea what updates will be made by the Moonlight Embedded devs and Raspian devs, so please read the verbose version after this and use the hyperlinks in it if you want to be sure it's all still valid.)

  1. Install Bullseye 32 bit lite with Raspberry Pi Imager on a 4GB or higher USB device.  Make sure to set localization and, if using wifi, your wifi credentials with OS Customization.
  2. Plug in Keyboard, Mouse, and xBox controller to USB ports on Pi.
  3. Run first boot, and at the command line
  4. curl -1sLf 'https://dl.cloudsmith.io/public/moonlight-game-streaming/moonlight-embedded/setup.deb.sh' | distro=raspbian sudo -E bash
  5. sudo apt install moonlight-embedded
  6. sudo apt update
  7. sudo apt upgrade
  8. sudo nano /boot/config.txt and change "dtoverlay" to be dtoverlay=vc4-fkms-v3d
  9. sudo raspi-config and turn on 
    1. autologin, 
    2. Network at boot, and 
    3. set the GPU Memory to 256.
    4. If it doesn't reboot for you, do another sudo reboot
  10. Pair Moonlight with: moonlight pair.  (You'll need to get the Pair code from your PC running Sunshine.)
  11. Test moonlight with: moonlight stream -1080 -app "Desktop"
  12. Exit moonlight with: Shift-Ctrl-Option-Q
  13. Establish SYSTEMD service file:
    sudo nano /lib/systemd/system/moonlight.service
  14. Text of moonlight.service should read:

  15. [Unit]
    Description=StartMoonlight
    After=network.target

    [Service]
    ExecStart=moonlight stream -1080 -app "Desktop"
    #Restart=always
    User=pi

    [Install]
    WantedBy=multi-user.target

    (Note, the Restart=always is just needed if you want to auto-restart due to some kind of failure.  The # in front means it is disabled/commented out.)

  16. Test with: sudo systemctl start moonlight.service
  17. Quit Moonlight with Shift-Ctrl-Alt-Q.
  18. Now, we need to enable the service to run on every reboot with: 
    sudo systemctl enable moonlight.service
  19. And now, do a sudo reboot
  20. Enjoy your autobooting moonlight Raspberry Pi3+!

---------------
Below is my patented horribly wordy, document for myself by typing outloud and probably never going back and editing guide to setting up Moonlight on an ancient, dusty Raspberry Pi 3B+!  Worked for me as of 8/11/24.

Background: Ok, so, I had this set up and working great... and then my card died magically one day... AND I realized I had forgot to back it up and make a standard image for myself.  It's not too hard to set up, except the Autoboot isn't obvious and various Reddit threads via Google searching give too many options.  This will be the 3rd or 4th time I've done it without documenting the steps because of setting up various versions on different dedicated and PINN implementations.   And, there are lots of help files I used along the way, so since I have to look it all up again, I figured I should document this time!

You can set this up as one of your PINN OS's if you want, or just as a straight full OS.  The whole build fits on a 4GB SD card or USB drive (I'm gonna see if it fits on a 1GB drive someday, since I have a bunch of 1 GB USB thumbdrives laying around).  And also, since it's essentially a dumb client to your PC with no involvement on your end other than turning it on, and doesn't do any read/write cycles really... you can run it with the Pi as a physically switched on/off device.

Yes... Essentially, what I do is just turn on my Pi, set my TV to the Pi's in port... and the mouse, keyboard, and xBox controller just "work" like I'm on my actual PC.  With wired ethernet, it's almost just like you're at your regular gaming PC.   (Even on wireless, the streaming speed and lag is remarkably good.)

Quite honestly, I'm blown away at how good this works.

What does this build get you?

  1. Install of Bullseye lite (Legacy 32 Bit version) of Raspbian OS for Raspberry Pi 3B+ (YMMV on other Pi's) using Raspberry Pi Imager (https://www.raspberrypi.com/software/).
  2. Install of Moonlight Embedded.  (https://github.com/moonlight-stream/moonlight-embedded)
    1. Must use the "Embedded" version on this age/vintage of Raspberry Pi.
  3. Command lines to configure Moonlight.
  4. Command lines to set up Moonlight to autoboot.
  5. I don't offer advice on how to set up Sunshine (Main site: https://app.lizardbyte.dev/Sunshine/ Download link as of today: https://app.lizardbyte.dev/Sunshine/?lng=en-US#Download  Github as of today: https://github.com/LizardByte/Sunshine) or Gamestream, but I must say that setting up Sunshine on my Windows PC's was one of the easiest, "set and forget" and "completely negligible impact on performance" things I've set up.  The only thing weird about it is it goes through a web browser for the interface.  Don't let that throw you.  It works fine, but if you're a person like me who keeps 8 billion tabs in 3 million windows open in my browser, it can become odd to wait for your browser to open up.



Alright...  Here's the verbose steps...
  1. Grab an SD card or USB card...  I will assume you have some familiarity with Raspberry Pi Imager and that you have a 4GB or bigger SD card or USB card.  
    1. I highly recommend testing said card with h2testw or similar.  The official site for h2testw is https://www.heise.de/.  As of this writing, the h2testw download page is https://www.heise.de/download/product/h2testw-50539.  Please note that h2testw is wonderful for testing and seeing real world speed with the simple idea of writing over your whole card and then reading it back for errors.  HOWEVER, I have found that it _won't_ detect when super cheap chinese knockoff cards have issues with holding the 10k and 100k and more files you might like to have on an emulation system.  This is because it only stores 10-100 or so files on a typical USB drive or card.
    2. If you plan to boot from USB, 2 lessons learned... 
      1. There's thorough but somewhat confusing documentation here:  https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#usb-boot-modes
      2. This Instructable cuts directly to what you actually need to do:  https://www.instructables.com/Booting-Raspberry-Pi-3-B-With-a-USB-Drive/
      3. Often, you need to use a powered USB hub to put enough power to some USB drives.  I've needed a powered USB hub to be consistent with a 128GB drive that had a huge old LED on it, and also a 256GB SSD in a USB enclosure.  Other USB zip drives work fine.  YMMV.

  2. In Raspberry Pi Imager, choose your Pi 3 from the list, and then choose the older Bullseye Lite 32bit.  Other lite versions can work, but the good ol 32bit is all we want and need here.

  3. Then, pick your storage, and when it asks you to do the customizations, I highly recommend doing that.  Yes, you can use Raspi-Config to do it yourself or to change anything.  But it's tedious setting your localizations that way, so please do that here.   (One thing to consider... If you plan on using only wired... consider NOT putting in your wireless even though you can.  No point in confusing the damn thing.)

    (Choose "Edit Settings" and then "Yes". )
    (If you want SSH enabled by default, make sure to do that under services)



  4. Ok, now you should have a bootable plain jane install...  One that you can either plug an mouse and keyboard in directly to in order to configure.  Or one that you can SSH / Terminal into use the settings you put in on the OS customization step.  Run the machine for the first time.

  5. Optional: If you're using SSH, figure out your IP address or use raspberry.local and get a terminal.  Example, since I'm using my MacBook to write and take screenshots, I went to my wireless router's device list, and found the raspberrypi and the IP, and then at the command line of terminal, you just type "ssh 192.168.1.xxx", accept the fingerprint, mess up the password, get the password right finally, and you're in!  Please note the note below... don't use the default password!


  6. Now, we install Moonlight.  Unless you're really into code and compiling, just do the "package" version of the instructions: https://github.com/moonlight-stream/moonlight-embedded/wiki/Packages

    NOTE: please use what they say on the proper github... but, for documentation sake, you can see them in the screenshot here...  First step is the curl instruction that does all the prelim setup.

    Then the next step... actually install moonlight-embedded... make sure you answer "y" for yes, and then be patient for a while...

    Now, twiddle your thumbs even more as you get everything updated...  Again, another "y" for you here...

  7. Ok, so you've rebooted, and now it wants you to login.  Yuck.  We want this thing to autoboot.  So, 
    1. log in (or SSH in), and then type "sudo raspi-config".
    2. Select "System Options".
    3. Choose "Boot / Auto Login".
    4. Choose "Console Autologin".
  8. Next, we are going to tell it to wait for the network connection on boot.  This is important, I think, because with an autoboot of moonlight, you want the network connection going before it actually tries to launch and connect.
    1. Select "System Options" again.
    2. Choose "Network at Boot".  And tell it YES, you want to wait.
  9. Next Raspi-Config option... we need to dedicate lots more GPU Memory, so,
    1. Select "Performance Options" this time.
    2. Go to "GPU Memory".
    3. Type in 256.
  10. Good optional Raspi-Config option... if you'd like... Go to the optional and "Expand Filesystem".  That's a standard RetroPi thing, and not necessarily necessary on this build.  But, you might as well...
  11. Other Raspi-Config options are really cool.  And if you didn't localize your keyboard and such with the Pi Imager, do that now to prevent headaches.  But, I won't be covering them here as we don't need to deal with them.  One thing that is kinda cool is that Moonlight does work and look great on a CRT if you want to use the composite output.  It's not perfect, but it's a pretty quick and dirty way to output a modern Windows PC to a classic CRT Retro Television.  Just make sure to tweak your Moonlight settings.

  12. Go ahead and exit RASPI-CONFIG and reboot.

  13. Now, you'll need to fix your graphics.  
    1. There is a separate section on here about needing to update via rpi-update first.  I didn't have this issue.  I did it once on one Pi and I didn't like what it did, but I forget why.  The trick to the fix if you don't run it and break your system....is that every PC/OS flavor and text editor can read and edit the config.txt file on your card if you didn't do the rpi-update and need to.  (OR, you can start all over again and just repeat these steps in this guide again...)
    2. So, either way, you need to change the graphics driver in config.txt.  If you've never used nano before, here's what you do.
    3. Enter "sudo nano /boot/config.txt"
    4. Use your arrow keys to navigate to the right section, and add an "f" to the dtoverlay string.  (This is the part you'd revert back to by removing the "f" if you, for some reason, needed to do the rpi-update step.)

    5. Then press "Control x" to exit.  Press "y" to save.  And press "ENTER" to confirm the file name.
    6. And, give it the old "sudo reboot".

  14. Now we configure MOONLIGHT EMBEDDED!
    1. Use the commands here to get yourself going: https://github.com/moonlight-stream/moonlight-embedded/wiki/Usage
    2. If you've used the graphical interface of Moonlight before, these commands roughly correlate to the UI you're used to.
    3. First we start by Pairing to the target PC.  
      1. REMINDER: This guide is intended to set you up with a single, auto-booting install to one PC.  Turn on Pi, Pi Boots, you see your remote computer.  ... You may not want that... If so, you can stop here and just always do command lines from now on.
      2. Type "Moonlight Pair", and if you're only running one Sunshine computer on your network, it should find it on the network, and give you a PIN to enter on that Sunshine computer.  Enter it, and Moonlight is happy at the command line.
        (If you forgot, the default password for sunshine is sunshine...)

  15. So now, you can try your first shot at streaming. 
    1. Default is the Steam application.  But, that's not what I like, I like the default Desktop, as you can then just use all of windows and then just launch Steam from the desktop like normal.
    2. Type in the following command line: moonlight stream -1080 -app "Desktop".
      1. Note, on the graphical interface, I often like to double the bitrate that's suggested.  You can do that here with "-bitrate <bitrate> Specify the bitrate in Kbps".  But... I forget here what that standard is because it wants it in Kbps and not Mbps and I'm just too lazy writing this right now to play with that.  It's not really important what I do as you can always play with the command lines until you get it right for yourself and your situation.
    3. And, if you did everything right, you should be off to the races and live and streaming your Sunshine hosted system as if you were right there at the PC (or whatever you put in for the -app parameter.
    4. Remember, Shift-Ctrl-Option-Q is how you quit out of Moonlight to get back to the command line.   If you're using a remote terminal, you don't need to worry as "sudo reboot" also lets you reboot.  Hey, for fun, you can Moonlight to your computer running the remote terminal and run terminal virtually which is super cool of course!

  16. Now, it's the part that I always need to look up and mess up...  Autobooting.  The reason I always mess this up is that there are MULTIPLE methods of automating start-up tasks.  (Example: Great encyclopedic articles like this (read, but don't try to use because it's not a code/example type article): https://www.dexterindustries.com/howto/run-a-program-on-your-raspberry-pi-at-startup/)  A few are deprecated but people love them anyway.  And a few are XWindows specific and don't apply here (I'm looking at you, autostart).  
    1. My best success is SYSTEMD.  #4 on the cool article I've crossed out above.  SYSTEMD, from what I've read, is the current modern and standard default way to launch things.   The problem is it's amazingly powerful and configurable to the point of not being easy obvious.  And, it also suffers from having a folder location change for the settings from version to version.  Joy.
    2. So, here's the straightforward steps I took to make it work.  (Many thanks to this page for having a very simple/clear "hello world" example that I modified just slightly.  https://www.makeuseof.com/what-is-systemd-launch-programs-raspberry-pi/)
    3. First, we create a service for moonlight launching: 
      sudo nano /lib/systemd/system/moonlight.service

    4. Then, we enter the following as the contents
      [Unit]
      Description=StartMoonlight
      After=network.target

      [Service]
      ExecStart=moonlight stream -1080 -app "Desktop"
      #Restart=always
      User=pi

      [Install]
      WantedBy=multi-user.target

      (Note, the Restart=always is just needed if you want to auto-restart due to some kind of failure.  The # in front means it is disabled/commented out.)

    5. Now, Control X, Yes, and Enter to save.
    6. Test it at the command line if you like with: 
      sudo systemctl start moonlight.service

    7. Remember, you can quit Moonlight with Shift-Ctrl-Alt-Q.
    8. Now, we need to enable the service to run on every reboot with: 
      sudo systemctl enable moonlight.service

    9. And now, do a sudo reboot.  And with any luck, you're done!
Hopefully, this all worked!  I'm NOT A LINUX EXPERT AND LEARNED ALL THIS BY THE HELP FILES OF THE REFERENCED AUTHORS AND A THOUSAND MESSAGE BOARDS.   THANK YOU.   If anything here is wrong, or needs edited, please let me know.  Thanks!

How to set up a self booting dedicated Moonlight (Sunshine client of Nvidia's GameStream) on a Raspberry Pi 3B+

8/11/2024:  This guide shows you how to set up a Raspberry Pi 3B+ (and older?) to stream your desktop PC from anywhere on your home network ...