Setting up a personal netplay relay server for Libretro / RetroArch


(last time edited: 2021-07-18)

tags: libretro, networking, server, games, retro, emulation

Libretro API

Libretro is a simple API that allows for the creation of games and emulators. It is very simple in nature, yet very powerful. The simplicity of it all requires some explanation in order to truly grasp how useful it can be to your own projects.

Libretro is the backend API to the wonderful RetroArch cross-platform emulator frontend. You can see the differences and specifications of both software in this brochure .pdf file. I'm not gonna get into details since this guide is specific for netplay.

Libretro Netplay

Netplay is RetroArch's mechanism for emulating local multiplayer over the internet, by continuously synchronizing multiple RetroArch instances running the same emulation core and same content. Currently, this approach is only for emulating classic single-system local multiplayer, not link cable play or network multiplayer modes.

If you are a programmer you can read the source code hosted as GitHub. It's written in C. Take a look at it by click here.

Libretro Netplay is not specifically bound to RetroArch. RetroArch is just one of the many frontends that implement this networking feature, and it's the most well featured one. There are other frontends using similar netcode to Libretro's netplay such as Batocera and Fightcade. Fightcade uses GPPO, a different netcode programmed by Tony Cannon made for arcade fighting games specifically but it can be used for any kind of game. It works amazingly good just as Libretro's Netplay. Having tested both locally and remotely I must say I cannot find any difference between connections with 40ms~90ms latency. Also, RetroArch can be used to play with more than 2 players and it works great too! Games for SNES with Multitap are waiting for you!

Libretro Netplay can be a pain in the ass if you do not know how to set up everything correctly. When you host a game and someone joins (possibly your friend) the connection runs on P2P (using UDP and TCP ports), meaning that it is a direct connection. There are no servers manipulating the data between both parties except the routing. Netcode syncronization depends deeply on both connections. Geographical distance and latency are crucial. If one of both parties has a bad connection or is far away from the other, say goodbye to your game.

There are other factors that play an important role here. If one of both parties is behind double NAT there won't be a single chance for connection. Double NAT basically means that you are not exposed to the Internet correctly; your public IP is hidden behind another private network. This usually happens with ISP that for some reason don't want the client to be full control of the connection. Another reason could be misconfiguration between multiple routers.

Keep in mind. Emulators for these systems aren't suitable for netplay:

How can you troubleshoot your connection for Netplay? (No specific order.)

Deploying a personal Libretro Relay Server (MitM)

Relay is a service which relays data between two devices which are not able to connect to each other directly otherwise. This is usually due to both devices being behind a NAT and neither side being able to open a port which would be directly accessible from the internet.

A relay server listens to connected clients and bounce data from one point to another. Of course this server acts as a Man in the Middle (MitM) as we call the same to this network attack method. The relay server is just a man in the middle.

Thankfully the Libretro developers have openly published and licensed (with GPL-3.0) the relay server program. The server is written in C++. You can find it here in the GitHub repository. With this program we can host our server anywhere we want. Keep in mind our server won't be announced publicly to the RetroArch Lobby Browser. You and your partner will have to connect manually via IP and port.

Let's get going. Let's compile the program.

First install the dependencies. And install Git too if you haven't already.


Now clone the Git repository.

$ git clone

Change directory to the cloned repo.

$ cd netplay-mitm-server

Generate a Makefile using QMake.

$ qmake

Compile using Make.

$ make

Run the server.

$ ./mitm

Yes! It's that simple.

Your server will be listening on TCP and UDP 55435 by default for future connections.

Monitor your relay server

There are multiple tools and ways to check if a connection to your server is being established. Tcptrack is one of the many tools. Other tools can be: lsof, termshark, mtr, iproute2's ss, inetutils-traceroute, netstat, zmap, nmap, GNU netcat, openbsd-netcat

A simple command:

# tcptrack -i eth0 tcp port 55435


Securing our netplay host using iptables

When you host a game it's common to see people from other places joining and spectating your game. Not only they eat bandwidth and makes the game go bad. Latency goes up and hell can break loose. It can be annoying, but that's just the typical scenario.

Things can get extremely bad is this person knows an specific exploit in your hosted emulator and starts messing your with computer. Everything is possible.

To prevent damage let's secure our system network with a firewall rule. It's easy, fast, secure. You just need to know your friend's IP address. Tell him to open this website called and share the IP with you.

Using iptables you can allow only certain specific IP address to be able to connect your game that is listening in port 55435.

Run this beautiful one liner command as root. Don't forget to replace the IP with your friend's IP.

# iptables -I INPUT \! --src -m tcp -p tcp --dport 55435 -j DROP

INPUT means incoming connections. Dport is destination port. DROP is basically reject, -m is for match and -p for port.

or as an alternative in 2 commands:

# iptables -A INPUT -p tcp --dport 55435 -s -j ACCEPT

# iptables -A INPUT -p tcp --dport 55435 -j DROP

If you're worried you can use Telnet to test the listening port from another host.

$ telnet <ip> <port>

To double-check your current iptables rules.

# iptables --list

To remove all iptables rules.

# iptables --flush

Notice! Rules don't persists across reboots.

Creating a Void Linux pkg template for xbps-src

The Git repository doesn't offer a proper release for the server program but we can still make a package using a _githash constant. Well, variable in this case since it's shell language.

The template dating to the 30th December of 2019 should look like this:

# Template file for 'netplay-mitm-server'
makedepends="qt5-devel qt5-qmake"
short_desc="Relay server for Libretro netplay"
maintainer="me <>"

do_install() {
    vbin mitm netplay-mitm-server

If you are familiar with Void Linux xbps-src templates you should know the simple commands to compile, build and install. There is a guide I wrote on how to compile a tabletop online game using xbps-src with all the steps detailed. Click here to read it.

Running RetroArch's Libretro NetPlay via CLI

Load a core and a ROM for homely basic gameplay.

If your Linux distribution does NOT package RetroArch and cores separately in system directories, you must look in the ~/.config/retroarch/cores directory for downloaded cores.

$ retroarch -L /path/to/ /path/to/game.rom

For NetPlay as host.

$ retroarch -L /path/to/ /path/to/game.rom -H --nick <nick>

For NetPlay as client.

$ retroarch -L /path/to/ /path/to/game.rom -C 152.43.123.xx --nick <nick>

These -L arguments can be used to host games with custom cores too.

There is no need to add port unless the default 55435 has been changed by the host.

If you need to get more info output about errors add the -v argument.

Libretro cores

Emulators (cores) differ completely from each other. They are developed by different people, with different features, different programming languages, etc.

If you wanna look for an extensive documentation on each emulator click here.

These are the most stable and accurate and FLOSS emulators I prefer using. These cores filenames end in .so because they are Shared Object files.

For great comparison between emulators please refer to this website: EMUGEN

NOTICE! Genesis Plus GX, Snes9x and FB Alpha are not FLOSS, but they are high accuracy emulators.

Regarding Mega Drive / Genesis games: some games require MD Joypad 6 Button enabled, list of games that support 6 buttons here. (Examples: Mortal Kombat games, Comix Zone, Batman Forever, Primal Rage, Streets of Rage 3, Street Fighter games, etc.)

For more info of each Libretro core, look for each file ending in .info inside /path/to/retroarch/.config/cores directory. Show features, description, BIOS info, etc.

Sometimes I recommend using the standalone programs rather than using Libretro cores. Using other frontends such as Mednafen and Ares is great too!

Input configuration

The RetroPad is a joypad abstraction interface defined by the Libretro API. It is the primary input device for a libretro frontend. Unless a core absolutely requires the use of a keyboard with no possible fallback for gamepad-type controls, a Libretro core should always be implemented as such that it is directly controllable by the RetroPad. For more information look at this documentation.

RetroPad is an implementation / standard that is implemented in Libretro. This specification serves as an abstraction to remap all controllers.

You must always remember to configure your controller first in: Settings -> Input -> Port X.

And then remap for every core when you're in-game: Press F1 and go to Main Menu -> Quick Menu -> Controls.

BIOS files for PlayStation (PSX) emulation

Some games, for example Castlevania: Symphony of the Night (PSX) require a SCPH5501 version BIOS for state saving the game in a virtual/emulated memory card. I recommend looking up these BIOS files and double checking the md5sum hash on the Internet and download them all.

BIOS files go in ~/.config/retroarch/system directory. If you are using RetroArch from flatpak they go in $HOME/.var/app/org.libretro.RetroArch/config/retroarch/system. Random note: If you are using the Mednaffe standalone front-end client, BIOS files go in $HOME/.mednafen/firmware.

BIOS files for SEGA Saturn emulation

BIOS files for Game Boy Advance

Useful tips and websites

I totally recommend to keep a nice and tidy ROM collection. RetroArch can help a lot by automatically download all box arts thumbnails. They are usually stored at ~/.config/retroarch/thumbnails/${SYSTEM} - ${CONSOLE}/Named_Boxarts. This way you can find games for specific regions with thumbnails available.

Not only I double-check for specific region-games via thumbnails, NTSC games and some exceptions for PAL games with 60hz (PS2), but also for console-only games. Extremely recommendable if you wanna keep a good collection.

These are some of the websites that help me finding little gems released in NTSC and PAL.

And finally games only released and exclusive for the console with no ports on PC. This is quite an extreme practice because games ported to Microsoft Windows system are very bad. Often without support and incredible hard to find. Games like Resident Evil, Silent Hill, Devil May Cry, Dino Crisis, etc... play way better on consoles and being emulated. There are options like open-source engine implementations for games like Resident Evil and I totally encourage using them. It's up to you and your needs.

Another thing to pay attention to is hertz frequency. European games, most commonly known as PAL games run at 50hz rather than 60hz. Here is a very well documented informative comparison. Europeans implemented this norm to save energy and they don't give a fuck about your video games.

Emulators also emulate the frequency, so if you were expecting to play an european rom at 60hz, it will not happen unless you apply a nasty hack or configure the emulator (only if the emulator lets you do it). I do not recommend doing this. You should always play USA games at all costs.

Some PlayStation 2 games include a Hertz Frequency Selection menu before the start menu. Thankfully a nice person on the Internet took the time to list all games supporting this feature. You can see the list at this website. The list is missing some games but it should be enough to double check the most popular games.

Checking ROM validity

If you wanna check your ROMs hash and validity go to this website managed by the No-Intro group. People from all over the world can upload their own cartridge ROM dumps. This helps greatfully with the preservation of retro games and it also helps gamers to play, store and share the correct game data.

Check this example. To this date there are 7 dumps from different people of the same Castlevania Bloodlines (USA) cartridge here. All hashes match and so far there are not strange uploads. You can try testing it yourself. If your ROM doesn't match with the one on this site, it's probably corrupt or something else happened.