This article has a personal touch. Sure, it’s a (somewhat) technical article, but I mainly did this for my girlfriend. I never documented this, but now that I made a personal website with Hugo, I decided it’s worth a post.

This took place somewhere in late spring / early summer 2023. Me and my girlfriend only knew each other a couple of months and we were just getting steady. We didn’t live together during this time yet.

I remembered she loves all things Harry Potter, and a few days earlier she mentioned this video game I wasn’t familiar with yet: Hogwarts Legacy 🪄. She didn’t own a gaming console, nor a system with a modern graphics card, so she never got to play it, but always wanted to. I still had my RTX 2070 Super from before the GPU prices started to surge somewhere between 2020-2023.

Not much later I decided to buy her that game, Hogwarts Legacy, on Steam, as a gift. I hooked up my good old Xbox 360 Controller I still had lying around and started the video game. After some fiddling with some Proton settings I managed to get ray tracing to work:

PROTON_FORCE_LARGE_ADDRESS_AWARE=1 PROTON_HIDE_NVIDIA_GPU=0 PROTON_ENABLE_NVAPI=1 VKD3D_CONFIG=dxr gamemoderun %command%

I quit the game and later that evening when she came over I surprised her with the video game and she started playing on my computer. She was very happy 🙂.

But sitting at my desk wasn’t as comfortable as sitting on my couch with my 65" screen. I therefore installed Sunshine on my desktop, and Moonlight on my Chromecast with Google TV 4K. Then I paired my controller with my Chromecast, and managed to play Hogwarts Legacy from my desktop, on my TV screen, sitting on my couch.

First I created a new unprivileged 'steam' user on my desktop, and have it automatically login as the system boots (I use EndeavourOS 🐧 with GNOME and the fish shell, YMMV):

user $ sudo useradd -m steam
user $ echo "AutomaticLogin=steam"
user $ grep -q '^AutomaticLogin=' /etc/gdm/custom.conf && sed -i \
         's/^AutomaticLogin=.*/AutomaticLogin=steam/' /etc/gdm/custom.conf || \
         echo 'AutomaticLogin=steam' >> /etc/gdm/custom.conf

I then installed and configured Sunshine, and configured the system to launch both Steam and Sunshine at login:

# Install Sunshine
user $ yay -S --needed aur/sunshine-bin

# Open ports
user $ for port in 47984/tcp 47989/tcp 48010/tcp 47998-48000/udp 48000/udp 48002/udp
         sudo firewall-cmd --permanent --zone=public --add-port=$port
       end

# https://docs.lizardbyte.dev/projects/sunshine/en/latest/about/setup.html
# 
# Sunshine needs access to uinput to create mouse and gamepad events.
# Create and reload udev rules for uinput
user $ echo 'KERNEL=="uinput", SUBSYSTEM=="misc", OPTIONS+="static_node=uinput", TAG+="uaccess"' | \
         sudo tee /usr/lib/udev/rules.d/60-sunshine.rules
user $ sudo udevadm control --reload-rules
user $ sudo udevadm trigger
user $ sudo modprobe uinput

# https://docs.lizardbyte.dev/projects/sunshine/en/latest/about/setup.html
# 
# Enable permissions for KMS capture
user $ sudo setcap cap_sys_admin+p (readlink -f (which sunshine))

# Automatically start Steam and Sunshine at login
user $ sudo cp /usr/share/applications/{steam,sunshine}.desktop /home/steam/.config/autostart/
user $ sudo chown steam:steam /home/steam/.config/autostart/{steam,sunshine}.desktop

I logged in as the 'steam' user and logged into Steam. In short, I then configured Sunshine, installed Moonshine on the Chromecast, and paired Moonlight to Sunshine. When Sunshine was up and running I also added a Hogwarts Legacy launcher to Sunshine using my web browser. You can achieve the same result by editing the JSON configuration file:

steam $ jq '.apps += [{"name": "Hogwarts Legacy", "output": "", "cmd": "", "exclude-global-prep-cmd": "false", "elevated": "false", "image-path": "\/home\/steam\/.config\/sunshine\/covers\/igdb_136625.png", "detached": ["setsid steam steam://rungameid/990080"]}]' /home/steam/.config/sunshine/apps.json > ~/apps.json
steam $ mv ~/apps.json ~/.config/sunshine/apps.json

I later also managed to run the game without the occasional crash every few runs:

user $ echo 'vm.max_map_count=1000000' | sudo tee /etc/sysctl.d/99-hogwarts.conf
user $ sudo sysctl -w
hogwarts legacy at my place

She loved playing Hogwarts Legacy. In fact, she wanted to play a lot more, but that meant leaving Loki 🐈 alone all day when she was working at the office, and afterwards at my place.

And who could leave the poor thing?

Loki

I wanted to find a way for her to game remotely and wondered if I could use WireGuard on the Chromecast to connect to my home LAN over the Internet. This would let her link the Chromecast to her TV at home, and stream the game from my place to hers. Since I already used WireGuard on my OpenWrt router for my phone, it should be pretty straightforward. I installed WireGuard on the Chromecast through the Play Store and set up a new WireGuard profile to connect it to my home router.

[Interface]
PrivateKey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Address = xxx.xxx.xxx.55/32, xxxx:xxxx:xxxx:xxxx::55/128
DNS = xxx.xxx.xxx.xxx, xxxx:xxxx:xxxx::xxxx

[Peer]
PublicKey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
PresharedKey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
AllowedIPs = xxx.xxx.xxx.xxx/32, xxxx:xxxx:xxxx:xxxx::1/128
Endpoint = xxx.xxx.xxx.xxx:xxxxx

On my OpenWrt router, I added the following configuration to '/etc/config/network' (replace with your own keys, ports, and addresses):

config interface 'wg0'
        option proto 'wireguard'
        option private_key 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
        option listen_port 'xxxxx'
        list addresses 'xxx.xxx.xxx.1/24'
        list addresses 'xxxx:xxxx:xxxx:xxxx::1/112'

config wireguard_wg0
        option description 'kijkbuis'
        option public_key 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
        option preshared_key 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
        option route_allowed_ips '1'
        list allowed_ips 'xxx.xxx.xxx.55/32'
        list allowed_ips 'xxxx:xxxx:xxxx::55/128'
        list allowed_ips 'xxxx:xxxx:xxxx:xxxx::55/128'
Note
This is not a WireGuard tutorial. See the official Quick Start to learn more.

This worked! I then gifted her an identical Chromecast, installed WireGuard and Moonlight, and connected it to my router via its public IP address. She also got my old controller so she could play Hogwarts Legacy at home, with me and Loki 🐈 next to her on the couch.

hogwarts legacy at her place

A few months went by and she finished the game playing Slytherin house 🐍. During that time we also had our first holiday together to Crete (Greece) in summer. Not much later I moved in with her in late autumn, early winter. We no longer need to use WireGuard on the Chromecast, but we still sometimes play a video game or two using Moonshine on our TV.