# Download sources and RomM Games on a server in your network, shown in the Library and downloaded to the console to play. ## Quick start with RomM Download sources and save sync both work with a [RomM](https://github.com/rommapp/romm) server in your network (5.0.0 or newer for the save sync). In short: 1. **Put the games on the server.** Games go to RomM's library under `roms/switch/`: a game as one `.nsp` or `.xci` file, or as a folder with the game's file, its updates in `update/` and its DLC in `dlc/`. Then start a scan in RomM (its **Scan** page) so it lists them. 2. **One RomM user per person.** Each person who plays on the console gets a user of their own in RomM; their save data stays apart on the server. 3. **Downloads.** In RomM, create a client API token (your profile, **Client API tokens**) with the scopes `platforms.read` and `roms.read`. Write `/data/prosperoeden/config/remote/sources.json` over FTP with the server's address and that token (see [Download sources](#download-sources)), start an FTP server on the console on port 2121 (ftpsrv), and open **Settings > Downloads**: the server and its games show up, and the Library lists them. 4. **Save sync.** Open **Settings > Save sync**, Cross on a profile and choose the server. Scan the QR code with your phone, sign in to RomM as that profile's user and approve the code. From then on the profile's save data is synced before and after each game (see [Save sync](SAVES.md#save-sync)). Pairing uses the server from `sources.json`; without download sources, fill in `save-sync.json` over FTP instead. The save sync does not need the FTP server. ## Download sources A download source is a server in your network that has games, such as a [RomM](https://github.com/rommapp/romm) server. Its games show up in the Library without taking any space on the console. A game is downloaded to the game files folder when you want it; from then on it is a game on the console like one you copied there. Nothing is streamed. **Downloads need an FTP server running on the console** (port 2121, see below): it writes the downloaded files. - **Set them up.** Make sure an FTP server runs on the console, then save `/data/prosperoeden/config/remote/sources.json` on the console (over FTP, like the keys) and open **Settings > Downloads**, or reopen ProsperoEden. It lists the sources, each with its `"type"`, a `"name"` for the menu and what that type needs (see [RomM](#romm) for a RomM server): ```json { "sources": [ { "type": "romm", "name": "Home", "url": "http://192.168.1.20:3000", "token": "rmm_..." }, { "type": "romm", "name": "Office", "url": "https://games.example.org", "token": "rmm_..." } ] } ``` **Settings > Downloads** shows each source, whether it answered, and why not when it did not, and the FTP server's port. Without a source it shows what the file is called, with an example for a RomM server. When you ask it to read the lists again (Cross on a source), it says when they are in. - **The Library.** The sources' games are listed with the console's own, by name, with their cover. A game that is not on the console has a darker cover with a cloud, and instead of NSP or XCI the line under it names its source (or how many have it), or says **Queued**, how far its download is, or **Download failed**. Its details name its sources. The same game on several sources is listed once, and a game that is on the console already is not listed again. Its settings, mods and console mode are there once it is downloaded. - **Which game is which.** Each source says what it knows of a game: its title ID, its ids at metadata providers (IGDB, ScreenScraper and the like) and whether its name comes from such metadata. Two sources' games are the same game when the first of these that both know agrees: the title ID, then an id at a provider both have one of, then the name (when both names come from metadata; case, accents and punctuation do not count), else the file name. A game on the console is the source's game when it has the file name the source gives it (a downloaded one does), else when their title IDs agree (when the source knows one), else by its name. - **Play.** Cross on a game that is not on the console downloads it first. A ring shows how far it is and the time left, and the game starts once all of it is there. Circle lets it download in the background without starting it; Square cancels it. When several sources have the game, ProsperoEden asks which one first. - **Download ahead.** Square on such a game puts it in the download queue, and Square again takes it out. The queue downloads one game at a time while the menu is open, also after ProsperoEden was closed and opened again. **Settings > Downloads** lists it: Square cancels a download, Cross tries a failed one again, and Cross on a source reads the sources' game lists again (also done by itself when the menu opens after more than 15 minutes). - **Where the files go.** The game's file goes to `roms/`, under its name on the source; its updates and DLC go to `updates/`. What a source counts as the game, an update or DLC is up to it (a RomM server: its file categories). A game downloaded from a source keeps the file name it has there. Only `.nsp` and `.xci` files are downloaded, and an entry without a game file (an update or DLC on its own) is not listed. - **An FTP server on the console.** Downloads are written by an FTP server running on the console (such as [ftpsrv](https://github.com/ps5-payload-dev/ftpsrv), which most setups have for copying the keys), on port 2121: ProsperoEden hands it the bytes over loopback. Written by the app itself, a game of several gigabytes slowed the drive down to a few MB/s and stopped the menu; from a payload the drive keeps its speed. Without such a server a download fails and says so. `"ftp_port"` next to `"sources"` names another port (etaHEN's own FTP server, for example), and `"ftp_user"` and `"ftp_password"` a sign-in when the server asks for one (else `anonymous`). The server must support `REST` with `STOR`, to go on with a download. - **Interrupted downloads.** A download is written to `.remote-downloads/` in the game files folder, and once all of the game's files are complete they are moved to `roms/` and `updates/`, so those folders only ever hold whole files of whole games. It stops while a game runs and when ProsperoEden closes, and goes on from where it was the next time the menu is open; the last 4 MB are downloaded again then, in case the console lost power while they were written. A cancel deletes what was downloaded (and never touches `roms/` or `updates/`), and what `.remote-downloads/` holds for a game that is not in the queue is deleted when the menu opens, so nothing is left behind. When the drive is full, the download stops and says so, as the FTP server reports it ("No space left on device"); nothing reaches `roms/` or `updates/`, what was downloaded stays in `.remote-downloads/`, and once there is room, Cross on it in **Settings > Downloads** goes on from there (Square cancels it and deletes it). The drive's free space is not checked before a download starts: an app on the console cannot ask for it. - **Checked as it comes.** RomM does not hash these files, so a download is checked on its way in, as Eden's integrity check checks a game: each NCA of an NSP or XCI against the SHA-256 it is named after, with no keys needed. A file found damaged is deleted and the download fails saying so; trying again downloads it again. A download that goes on reads what it had from the drive first (**Checking** in the queue). What the console's FTP server writes is not read back, and files that are no NSP or XCI are taken as they are. - **Making room.** A game that a source has can be deleted from the console again: Triangle in the Library, then **Delete from console** (Cross twice). Its file and all of its updates and DLC in `updates/` are deleted, also ones put there by hand; its save data, its settings and its mods stay. The Library then lists it as on its sources again, and it can be downloaded any time. Sign-ins are kept in `sources.json` only, and each is sent to its own source only. They are stored there as plain text, and whoever can reach the console's FTP server can read the file: give a source a token made for it, with only the scopes it needs, rather than your password. A file that is on the console already is never replaced by a download of the same name. Download sources need filesystem access (the payload loader on port 9021), as the game files folder does, and an FTP server on the console (see above). Save data is synced apart from the sources; see [Save sync](SAVES.md#save-sync). ### RomM `"type": "romm"` is a [RomM](https://github.com/rommapp/romm) server (a current version); as with any source, its games are written by the console's FTP server, which has to run. Its entry in `sources.json` has the server's `"url"` and a `"token"`: in RomM, create a client API token (your profile, **Client API tokens**) with the scopes `platforms.read` and `roms.read`. `"username"` and `"password"` work instead of `"token"`, and `"platform"` names the platform's slug when the server does not call it `switch`. RomM's file categories decide what is the game and what are its updates and DLC; manuals, mods, soundtracks and the like stay on the server. In RomM a game is a folder, with its updates in `update/` and its DLC in `dlc/`. What RomM matched a game to tells it apart: its ids at the metadata providers RomM uses, its name when RomM identified it, and its title ID when the RomM server has the keys to read it.