Skip to content

Instantly share code, notes, and snippets.

@jakebrinkmann
Last active January 23, 2026 20:37
Show Gist options
  • Select an option

  • Save jakebrinkmann/577dfbb8a63f382cd5ed87f50a662b31 to your computer and use it in GitHub Desktop.

Select an option

Save jakebrinkmann/577dfbb8a63f382cd5ed87f50a662b31 to your computer and use it in GitHub Desktop.
Retroarch gaming setup
TIMEZONE=America/Chicago
PUID=1001
PGID=1001
CONFIG_PATH=/configs
MEDIA_PATH=/mnt/media
ROMS_PATH=${MEDIA_PATH}/roms

${PROJECT}

"A good game is like a good book or a good movie, it transports you to another world." -- Shigeru Miyamoto, game designer

Batocera.linux is a popular choice for retro gaming enthusiasts due to its ease of use, extensive compatibility, and seamless user experience. An open-source and completely free retro-gaming distribution, it can be copied to a USB stick or SD card, turning any computer/nano computer into a gaming console. It supports many emulators and game engines out of the box.

Warning

Seems like batocera conflicts with Plex/*arr server setup

Hardware

Misc Setup

cat >> ~/.ssh/config <<EOF
Host batocera.local
    StrictHostKeyChecking no
    UserKnownHostsFile=/dev/null
EOF
ssh root@batocera.local

curl -fSLo /tmp/BIOS.zip \
  https://github.com/Abdess/retroarch_system/releases/download/v20220308/Batocera_V34-dev.zip \
  && unzip -n /tmp/BIOS.zip -d /userdata/

ln -sf \
  "/media/TOSHIBA_3TB_EXT/downloads/Nintendo - N64/" \
  /userdata/roms/n64/

ln -sf \
  "/media/TOSHIBA_3TB_EXT/downloads/Nintendo - GameCube/" \
  /userdata/roms/gamecube/

ln -sf \
  "/media/TOSHIBA_3TB_EXT/downloads/Nintendo - Game Boy Advance/" \
  /userdata/roms/gba/

# > it is recommended to use direct downloads with a download manager instead of torrents...
# - https://r-roms.github.io/megathread/popular/
#!/bin/bash
# Batocera Update Script - Version 40
# Date: 2024-12-10
# Set the Batocera image URL and download directory
FILE_URL="https://updates.batocera.org/x86_64/stable/last/batocera-x86_64-40-20240801.img.gz"
DOWNLOAD_DIR="/tmp"
# Step 1: Download the specified Batocera image to /tmp
echo "Downloading the Batocera image from $FILE_URL to $DOWNLOAD_DIR..."
IMAGE_FILE="$DOWNLOAD_DIR/$(basename $FILE_URL)"
curl -fSLo $IMAGE_FILE $FILE_URL
# Step 2: Prompt the user to choose the target USB device
echo "Identifying available USB drives..."
echo "Available drives and descriptions:"
lsblk -o NAME,SIZE,MODEL,TYPE | grep disk
echo ""
echo "WARNING: Be careful to select the correct drive. Writing to the wrong drive will erase all data on it."
read -p "Enter the target drive name (e.g., sda, sdb, etc.): " TARGET_DRIVE
if [ -z "$TARGET_DRIVE" ]; then
echo "No drive selected. Exiting."
exit 1
fi
TARGET_PATH="/dev/$TARGET_DRIVE"
# Confirm the user's choice
echo "You selected $TARGET_PATH. Are you sure you want to proceed? (yes/no)"
read -r CONFIRM
if [ "$CONFIRM" != "yes" ]; then
echo "Operation canceled by user."
exit 1
fi
# Step 3: Extract and write the image to the target drive
IMAGE_FILE="$DOWNLOAD_DIR/$(basename $FILE_URL)"
echo "Flashing Batocera image to $TARGET_PATH..."
gunzip -c $IMAGE_FILE | sudo dd status=progress of=$TARGET_PATH conv=fsync
sync
sudo eject $TARGET_PATH
echo "#================================================================================"
echo "Image flashed and drive ejected."
echo "#================================================================================"
#================================================================================
# SSH Access
# Access Batocera via SSH using one of the following:
# Default username: root
# Default password: linux
echo "Access Batocera via SSH:"
echo " ssh root@batocera.local or ssh root@<Batocera_IP>"
# Editing Boot Configuration
echo "To edit the boot configuration:"
echo " vi /boot/batocera-boot.conf"
# Audio Setup
echo "To configure audio settings:"
echo " - Navigate to System Settings > Hardware Audio Output."
# Example: Checking KODI audio passthrough settings
echo "To verify KODI settings:"
echo " grep -RI hdmi .kodi/userdata/"
# Check for updates
echo "To update to a new version:"
echo " batocera-check-updates butterfly"
echo " batocera-upgrade https://updates.batocera.org/x86_64/butterfly/last"
echo "#================================================================================"
echo "All tasks completed. Enjoy your Batocera setup!"
echo "#================================================================================"
services:
emulatorjs:
image: lscr.io/linuxserver/emulatorjs
container_name: emulatorjs
ports:
- 3000:3000 # configuration backend
- 80:3080 # WebApp
# - 4001:4001 # IPFS peering (for artwork)
volumes:
- ${ROMS_PATH}:/data
- ${CONFIG_PATH}/emulatorjs:/config # store user profiles
environment:
- PUID=${PUID}
- PGID=${PGID}
- TZ=${TIMEZONE}
restart: unless-stopped
watchtower:
image: containrrr/watchtower
container_name: watchtower
environment:
- TZ=${TIMEZONE}
- WATCHTOWER_CLEANUP=true
- WATCHTOWER_INCLUDE_STOPPED=true
- WATCHTOWER_SCHEDULE=0 0 3 * * *
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# romm:
# image: rommapp/romm:latest
# container_name: romm
# restart: unless-stopped
# environment:
# - DB_HOST=romm-db
# - DB_NAME=romm # Should match MARIADB_DATABASE in mariadb
# - DB_USER=romm-user # Should match MARIADB_USER in mariadb
# - DB_PASSWD=${MARIADB_PASSWORD} # Should match MARIADB_PASSWORD in mariadb
# volumes:
# - romm_resources:/romm/resources # Resources fetched from IGDB (covers, screenshots, etc.)
# - romm_redis_data:/redis-data # Cached data for background tasks
# - /path/to/library:/romm/library # Your game library. Check https://github.com/rommapp/romm?tab=readme-ov-file#folder-structure for more details.
# - /path/to/assets:/romm/assets # Uploaded saves, states, etc.
# - /path/to/config:/romm/config # Path where config.yml is stored
# ports:
# - 80:8080
# depends_on:
# romm-db:
# condition: service_healthy
# restart: true
#
# romm-db:
# image: mariadb:latest
# container_name: romm-db
# restart: unless-stopped
# environment:
# - MARIADB_ROOT_PASSWORD= # Use a unique, secure password
# - MARIADB_DATABASE=romm
# - MARIADB_USER=romm-user
# - MARIADB_PASSWORD=${MARIADB_PASSWORD}
# volumes:
# - mysql_data:/var/lib/mysql
# healthcheck:
# test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
# start_period: 30s
# start_interval: 10s
# interval: 10s
# timeout: 5s
# retries: 5
#
# volumes:
# mysql_data:
# romm_resources:
# romm_redis_data:
#!/bin/bash
# Base directory for RetroArch downloads
BASE_DIR="$HOME/.config/retroarch/downloads"
# Define your list of games here.
# Format: "System Name|URL"
# (Use the exact folder name RetroArch expects, e.g., "Nintendo - GameCube")
declare -a GAMES=(
# EXAMPLES (Homebrew / Legal Demos):
"Nintendo - GameCube|https://example.com/legal_game_backup.rvz"
"Nintendo - Game Boy Advance|https://example.com/homebrew_game.gba"
"Sony - PlayStation Portable|https://example.com/homebrew_demo.iso"
)
echo "Starting download manager..."
for entry in "${GAMES[@]}"; do
# 1. Split the string into System and URL
SYSTEM="${entry%%|*}"
URL="${entry##*|}"
# 2. Extract the filename from the URL (removes messy %20 stuff if simpler)
FILENAME=$(basename "$URL" | sed 's/%20/ /g')
# 3. Create the specific console directory
TARGET_DIR="$BASE_DIR/$SYSTEM"
mkdir -p "$TARGET_DIR"
echo "Processing: $FILENAME"
echo " -> Target: $TARGET_DIR"
# 4. Download directly into the target folder
# We use -L to follow redirects and -o to specify the full output path
if curl -L -o "$TARGET_DIR/$FILENAME" "$URL"; then
echo " [SUCCESS] Downloaded."
else
echo " [ERROR] Failed to download."
fi
echo "------------------------------------------------"
done
echo "All tasks complete."
sudo pacman -Rns linux54
sudo pacman -R linux-lts-meta
sudo pacman -Syyyu
sudo pacman -Sy archlinux-keyring manjaro-keyring
sudo pacman -Syu retroarch
sudo pacman -S retroarch-assets-xmb retroarch-assets-ozone retroarch-assets-glui
sudo pacman -S libretro-mame libretro-snes9x libretro-gambatte libretro-mgba libretro-dolphin libretro-mupen64plus-next libretro-ppsspp
sudo pacman -S vulkan-intel

retroarch --verbose
# 1. Create the target directory (if it doesn't exist)
mkdir -p ~/.config/retroarch/cores/info

# 2. Download the latest info pack from the official Libretro buildbot
curl -L -o /tmp/info.zip https://buildbot.libretro.com/assets/frontend/info.zip

# 3. Extract it into your config folder (quietly overwriting old files)
unzip -o -q /tmp/info.zip -d ~/.config/retroarch/cores/info

# 4. Cleanup
rm /tmp/info.zip

CORES_DIR="$HOME/.config/retroarch/cores"
mkdir -p "$CORES_DIR"

# 2. Define the source (Libretro Buildbot for Linux x86_64)
BASE_URL="https://buildbot.libretro.com/nightly/linux/x86_64/latest"

# 3. List of cores to download
CORES=(
  "mame_libretro.so.zip"              # Arcade / Casino
  "snes9x_libretro.so.zip"            # SNES
  "gambatte_libretro.so.zip"          # Game Boy / Color
  "mgba_libretro.so.zip"              # Game Boy Advance
  "dolphin_libretro.so.zip"           # GameCube / Wii
  "mupen64plus_next_libretro.so.zip"  # Nintendo 64
  "ppsspp_libretro.so.zip"            # PSP
  "nxengine_libretro.so.zip"          # Cave Story
)

# 4. Loop through and download each one
for core in "${CORES[@]}"; do
    echo "Downloading $core..."
    curl -L -o "/tmp/$core" "$BASE_URL/$core"
    
    echo "Extracting to $CORES_DIR..."
    unzip -o -q "/tmp/$core" -d "$CORES_DIR"
    
    # Cleanup the zip file
    rm "/tmp/$core"
done

echo "Done! All cores are installed."

(cd ~/.config/retroarch/downloads; find . -name "*.zip" -execdir sh -c 'unzip -o "$1" && rm "$1"' _ {} \;)
# 1. Force the RDP (Video) plugin to ParaLLEl (Vulkan-native)
echo 'mupen64plus-rdp-plugin = "parallel"' >> ~/.config/retroarch/retroarch-core-options.cfg

# 2. Force the RSP (Audio/Processor) plugin to ParaLLEl (Matches the video)
echo 'mupen64plus-rsp-plugin = "parallel"' >> ~/.config/retroarch/retroarch-core-options.cfg
# file: ~/.config/retroarch/retroarch.cfg
# Change the video driver to Vulkan (Fixes Intel/Dolphin crash)
video_driver = "vulkan"
# make things fullscreen
video_fullscreen = "true"
video_window_show_decorations = "false"
video_windowed_fullscreen = "true"
# Unlock the Core Downloader (Fixes "No Cores Available")
libretro_directory = "/home/waterw/.config/retroarch/cores"
libretro_info_path = "/home/waterw/.config/retroarch/cores/info"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment