diff --git a/4.5.0/Getting-Started/Folder-Structure/index.html b/4.5.0/Getting-Started/Folder-Structure/index.html index 5761719..dff09a2 100644 --- a/4.5.0/Getting-Started/Folder-Structure/index.html +++ b/4.5.0/Getting-Started/Folder-Structure/index.html @@ -482,6 +482,30 @@ + + @@ -2038,6 +2062,30 @@ + + @@ -2237,77 +2285,221 @@
  • Other tags will also be imported, for example: tetris [1.0001](HACK)[!].gba
  • Tags can be used to search for games in the search bar. For example, searching for (USA) will return all games with the USA tag.

    -
    - +
    - -#### Supported Languages - -The following language tags are recognized by RomM: - -| Code | Language | -| ------ | ----------- | -| Ar | Arabic | -| Da | Danish | -| De | German | -| El | Greek | -| En | English | -| Es | Spanish | -| Fi | Finnish | -| Fr | French | -| It | Italian | -| Ja | Japanese | -| Ko | Korean | -| Nl | Dutch | -| No | Norwegian | -| Pl | Polish | -| Pt | Portuguese | -| Ru | Russian | -| Sr | Serbian | -| Sv | Swedish | -| Zh | Chinese | -| nolang | No Language | - +

    Supported Languages

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CodeLanguage
    ArArabic
    DaDanish
    DeGerman
    ElGreek
    EnEnglish
    EsSpanish
    FiFinnish
    FrFrench
    ItItalian
    JaJapanese
    KoKorean
    NlDutch
    NoNorwegian
    PlPolish
    PtPortuguese
    RuRussian
    SrSerbian
    SvSwedish
    ZhChinese
    nolangNo Language
    -
    - -#### Supported Regions - -The following region tags are recognized by RomM: - -| Code | Region | -| ---- | ------------- | -| A | Australia | -| AS | Asia | -| B | Brazil | -| C | Canada | -| CH | China | -| E | Europe | -| F | France | -| FN | Finland | -| G | Germany | -| GR | Greece | -| H | Holland | -| HK | Hong Kong | -| I | Italy | -| J | Japan | -| K | Korea | -| NL | Netherlands | -| NO | Norway | -| PD | Public Domain | -| R | Russia | -| S | Spain | -| SW | Sweden | -| T | Taiwan | -| U | USA | -| UK | England | -| UNK | Unknown | -| UNL | Unlicensed | -| W | World | - +

    Supported Regions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CodeRegion
    AAustralia
    ASAsia
    BBrazil
    CCanada
    CHChina
    EEurope
    FFrance
    FNFinland
    GGermany
    GRGreece
    HHolland
    HKHong Kong
    IItaly
    JJapan
    KKorea
    NLNetherlands
    NONorway
    PDPublic Domain
    RRussia
    SSpain
    SWSweden
    TTaiwan
    UUSA
    UKEngland
    UNKUnknown
    UNLUnlicensed
    WWorld
    -
    @@ -2331,7 +2523,7 @@ The following region tags are recognized by RomM: - 2025-12-30 + 2025-12-30 diff --git a/4.5.0/search/search_index.json b/4.5.0/search/search_index.json index 4598266..0bb2464 100644 --- a/4.5.0/search/search_index.json +++ b/4.5.0/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Introduction","text":"

    Welcome to the RomM Project, the premier self-hosted, open source ROM manager.

    Website | Demo

    RomM (ROM Manager) allows you to scan, enrich, and browse your game collection with a clean and responsive interface. With support for multiple platforms, various naming schemes, and custom tags, RomM is a must-have for anyone who plays on emulators.

    To get started with RomM, head over to the Quick Start guide.

    "},{"location":"#philosophy","title":"Philosophy","text":"

    At the heart of this project is a commitment to freedom, collaboration, and transparency. We believe that software should be built for the benefit of its users, rather than solely to maximize profit or serve the interests of a few stakeholders, ensuring that it doesn't manipulate, exploit, or prioritize data collection.

    By offering RomM as a self-hosted, open-source solution, we ensure that everyone has the ability to manage their game collections on their own terms, and own their data, all without being tied to proprietary systems or services.

    Rom is and will always be free and open-source software.

    The core app is licensed under GNU AGPLv3, which requires that all modifications to the code be made available under the same license. This ensures that the community can benefit from and build upon the contributions of others, promoting trust and transparency.

    Other projects under the umbrella will be licensed under similar permissive licenses, such as GNU GPLv3 for software, or CC0 for documentation.

    "},{"location":"#contributing","title":"Contributing","text":"

    RomM is a collaborative project, and we welcome contributions from the community. Our code is available on GitHub, and we encourage you to contribute to the project by submitting bug reports, feature requests, or pull requests. Please check the contribution guidelines in each project for more information.

    "},{"location":"#community","title":"Community","text":"

    We strive to create a safe and respectful space where everyone can contribute and benefit from the project by fostering a welcoming and inclusive environment for all users, regardless of their background or identity.

    Join us on Discord, where you can ask questions, submit ideas, get help, showcase your collection, and discuss RomM with other users.

    "},{"location":"API-and-Development/API-Reference/","title":"API Reference","text":""},{"location":"API-and-Development/API-Reference/#api-reference","title":"API Reference","text":"

    RomM provides a comprehensive REST API that allows you to programmatically interact with your RomM instance. Most API endpoints are authenticated and follow RESTful conventions.

    "},{"location":"API-and-Development/API-Reference/#interactive-documentation","title":"Interactive Documentation","text":"

    RomM automatically generates interactive API documentation using OpenAPI (Swagger). You can access the interactive API docs directly from your running instance:

    These interactive docs allow you to:

    "},{"location":"API-and-Development/API-Reference/#base-url","title":"Base URL","text":"

    The API base URL is typically:

    http://your-instance:3000/api\n

    Replace your-instance with your actual RomM instance URL or IP address.

    "},{"location":"API-and-Development/API-Reference/#authentication","title":"Authentication","text":"

    All API endpoints require authentication. RomM supports:

    When using OAuth2, you'll need to obtain a token from /api/token endpoint and include it in the Authorization header as Bearer <token>.

    "},{"location":"API-and-Development/API-Reference/#oauth2-scopes","title":"OAuth2 Scopes","text":"

    The API uses OAuth2 scopes to control access to different resources:

    Read Scopes:

    Write Scopes:

    "},{"location":"API-and-Development/API-Reference/#api-endpoints-overview","title":"API Endpoints Overview","text":"

    The RomM API provides comprehensive endpoints for managing all aspects of your ROM collection:

    "},{"location":"API-and-Development/API-Reference/#core-resources","title":"Core Resources","text":""},{"location":"API-and-Development/API-Reference/#supporting-features","title":"Supporting Features","text":"

    For complete endpoint documentation including request/response schemas, query parameters, and authentication requirements, visit the interactive API documentation at /api/docs or /api/redoc on your RomM instance.

    "},{"location":"API-and-Development/API-Reference/#example-usage","title":"Example Usage","text":""},{"location":"API-and-Development/API-Reference/#using-curl","title":"Using cURL","text":"
    # Get all libraries\ncurl -u username:password http://your-instance:3000/api/libraries\n\n# Get a specific ROM\ncurl -u username:password http://your-instance:3000/api/roms/123\n\n# Create a new ROM entry\ncurl -X POST -u username:password \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\": \"New ROM\", \"platform_id\": 1}' \\\n  http://your-instance:3000/api/roms\n
    "},{"location":"API-and-Development/API-Reference/#using-python","title":"Using Python","text":"
    import requests\nfrom requests.auth import HTTPBasicAuth\n\n# Setup authentication\nauth = HTTPBasicAuth('username', 'password')\nbase_url = 'http://your-instance:3000/api'\n\n# Get all libraries\nresponse = requests.get(f'{base_url}/libraries', auth=auth)\nlibraries = response.json()\n\n# Get a specific ROM\nresponse = requests.get(f'{base_url}/roms/123', auth=auth)\nrom = response.json()\n
    "},{"location":"API-and-Development/API-Reference/#using-javascriptnodejs","title":"Using JavaScript/Node.js","text":"
    const axios = require(\"axios\");\n\n// Setup authentication\nconst api = axios.create({\n    baseURL: \"http://your-instance:3000/api\",\n    auth: {\n        username: \"username\",\n        password: \"password\",\n    },\n});\n\n// Get all libraries\nconst libraries = await api.get(\"/libraries\");\n\n// Get a specific ROM\nconst rom = await api.get(\"/roms/123\");\n
    "},{"location":"API-and-Development/API-Reference/#openapi-specification","title":"OpenAPI Specification","text":"

    You can download the complete OpenAPI specification from your RomM instance:

    http://your-instance:3000/openapi.json\n

    This specification can be imported into API testing tools like Postman, used to generate client libraries, or used for API mocking.

    "},{"location":"API-and-Development/API-Reference/#getting-help","title":"Getting Help","text":"

    For API-specific questions or issues:

    1. Check the interactive documentation at /api/docs or /api/redoc on your instance
    2. Review the code in the RomM repository
    3. Open an issue on GitHub
    4. Join the Discord community
    "},{"location":"API-and-Development/Contributing/","title":"Contributing","text":""},{"location":"API-and-Development/Contributing/#contributing-to-romm","title":"Contributing to RomM","text":"

    Thank you for considering contributing to RomM! This document outlines some guidelines to help you get started with your contributions.

    If you're looking to implement a large feature or make significant changes to the project, it's best to open an issue first AND join the Discord to discuss your ideas with the maintainers.

    "},{"location":"API-and-Development/Contributing/#code-of-conduct","title":"Code of Conduct","text":"

    Please note that this project adheres to the Contributor Covenant code of conduct. By participating in this project, you are expected to uphold this code.

    "},{"location":"API-and-Development/Contributing/#ai-assistance-notice","title":"AI Assistance Notice","text":"

    [!IMPORTANT]

    If you are using any kind of AI assistance to contribute to RomM, it must be disclosed in the pull request.

    If you are using any kind of AI assistance while contributing to RomM this must be disclosed in the pull request, along with the extent to which AI assistance was used (e.g. docs only vs. code generation). If PR responses are being generated by an AI, disclose that as well. As a small exception, trivial tab-completion doesn't need to be disclosed.

    An example disclosure:

    This PR was written primarily by Claude Code.

    Or a more detailed disclosure:

    I consulted ChatGPT to understand the codebase but the solution was fully authored manually by myself.

    Failure to disclose this is rude to the human operators on the other end of the pull request, but it also makes it difficult to determine how much scrutiny to apply to the contribution.

    In a perfect world, AI assistance would produce equal or higher quality work than any human. That isn't the world we live in today, and in most cases it's generating slop.

    Please be respectful to maintainers and disclose AI assistance.

    "},{"location":"API-and-Development/Contributing/#contributing-to-the-docs","title":"Contributing to the Docs","text":"

    If you would like to contribute to the project's documentation, open a pull request against the docs repo. We welcome any contributions that help improve the documentation (new pages, updates, or corrections).

    "},{"location":"API-and-Development/Contributing/#adding-translations","title":"Adding Translations","text":"

    If you would like to translate the project into another language, create a new folder under the frontend/src/locales directory, and follow the existing language files as a template. Once you've created the new language file, open a pull request to add it to the project.

    "},{"location":"API-and-Development/Contributing/#how-to-contribute-code","title":"How to Contribute Code","text":"
    1. Fork the repository.
    2. Clone your forked repository: git clone https://github.com/your-username/romm.git
    3. Checkout the master branch: git checkout master
    4. Follow the steps in the developer setup guide
    5. Create a new branch for your feature/fix: git checkout -b feature-or-fix-name
    6. Make your changes and commit them with descriptive commit messages: git commit -am 'Add feature XYZ'
    7. Push your changes to your fork: git push origin feature-or-fix-name
    8. Open a pull request to the master branch of the original repository.
    "},{"location":"API-and-Development/Contributing/#pull-request-guidelines","title":"Pull Request Guidelines","text":""},{"location":"API-and-Development/Contributing/#code-style","title":"Code Style","text":"

    Follow the existing code style used throughout the project. If working with VSCode or a similar editor, consider installing these extensions:

    "},{"location":"API-and-Development/Contributing/#issue-reporting","title":"Issue Reporting","text":"

    If you encounter any bugs or have suggestions for improvements, please create an issue on GitHub. Provide as much detail as possible, including steps to reproduce the issue if applicable.

    "},{"location":"API-and-Development/Contributing/#licensing","title":"Licensing","text":"

    By contributing to RomM, you agree that your contributions will be licensed under the project's LICENSE.

    Thank you for contributing to RomM! Your help is greatly appreciated.

    "},{"location":"API-and-Development/Development-Setup/","title":"Development Setup","text":""},{"location":"API-and-Development/Development-Setup/#setting-up-romm-for-development","title":"Setting up RomM for development","text":""},{"location":"API-and-Development/Development-Setup/#option-1-using-docker","title":"Option 1: Using Docker","text":"

    If you prefer to use Docker for development, you can set up RomM using the provided Docker Compose configuration. This method simplifies the setup process by encapsulating all dependencies within Docker containers.

    "},{"location":"API-and-Development/Development-Setup/#environment-setup","title":"Environment setup","text":""},{"location":"API-and-Development/Development-Setup/#create-the-mock-structure-with-at-least-one-rom-and-empty-config-for-manual-testing","title":"Create the mock structure with at least one rom and empty config for manual testing","text":"
    mkdir -p romm_mock/library/roms/switch\ntouch romm_mock/library/roms/switch/metroid.xci\nmkdir -p romm_mock/resources\nmkdir -p romm_mock/assets\nmkdir -p romm_mock/config\ntouch romm_mock/config/config.yml\n
    "},{"location":"API-and-Development/Development-Setup/#copy-envtemplate-to-env-and-fill-the-variables","title":"Copy env.template to .env and fill the variables","text":"
    cp env.template .env\n
    ROMM_BASE_PATH=/app/romm\nDEV_MODE=true\n
    "},{"location":"API-and-Development/Development-Setup/#build-the-image","title":"Build the image","text":"
    docker compose build  # or `docker compose build --no-cache` to rebuild from scratch\n
    "},{"location":"API-and-Development/Development-Setup/#spin-up-the-docker-containers","title":"Spin up the Docker containers","text":"
    docker compose up -d\n

    And you're done! You can access the app at http://localhost:3000. Any changes made to the code will be automatically reflected in the app thanks to the volume mounts.

    "},{"location":"API-and-Development/Development-Setup/#option-2-manual-setup","title":"Option 2: Manual setup","text":""},{"location":"API-and-Development/Development-Setup/#environment-setup_1","title":"Environment setup","text":""},{"location":"API-and-Development/Development-Setup/#-create-the-mock-structure-with-at-least-one-rom-and-empty-config-for-manual-testing","title":"- Create the mock structure with at least one rom and empty config for manual testing","text":"
    mkdir -p romm_mock/library/roms/switch\ntouch romm_mock/library/roms/switch/metroid.xci\nmkdir -p romm_mock/resources\nmkdir -p romm_mock/assets\nmkdir -p romm_mock/config\ntouch romm_mock/config/config.yml\n
    "},{"location":"API-and-Development/Development-Setup/#-copy-envtemplate-to-env-and-fill-the-variables","title":"- Copy env.template to .env and fill the variables","text":"
    cp env.template .env\n
    "},{"location":"API-and-Development/Development-Setup/#-install-system-dependencies","title":"- Install system dependencies","text":"
    # https://mariadb.com/docs/skysql-previous-release/connect/programming-languages/c/install/#Installation_via_Package_Repository_(Linux):\nsudo apt install libmariadb3 libmariadb-dev libpq-dev\n\n# Build and configure RAHasher (optional)\n# This is only required to calculate RA hashes\n# Users on macOS can skip this step as RAHasher is not supported\ngit clone --recursive https://github.com/RetroAchievements/RALibretro.git\ncd ./RALibretro\ngit checkout 1.8.0\ngit submodule update --init --recursive\nsed -i '22a #include <ctime>' ./src/Util.h\nmake HAVE_CHD=1 -f ./Makefile.RAHasher\ncp ./bin64/RAHasher /usr/bin/RAHasher\n
    "},{"location":"API-and-Development/Development-Setup/#-install-python-dependencies","title":"- Install python dependencies","text":"

    You'll need uv installed

    https://docs.astral.sh/uv/getting-started/installation/

    curl -LsSf https://astral.sh/uv/install.sh | sh\n

    Then create the virtual environment and install the dependencies using uv:

    uv venv\nsource .venv/bin/activate\nuv sync --all-extras --dev\n
    "},{"location":"API-and-Development/Development-Setup/#-spin-up-the-database-and-other-services","title":"- Spin up the database and other services","text":"
    docker compose up -d\n
    "},{"location":"API-and-Development/Development-Setup/#-run-the-backend","title":"- Run the backend","text":"

    Migrations will be run automatically when running the backend.

    cd backend\nuv run python3 main.py\n
    "},{"location":"API-and-Development/Development-Setup/#setting-up-the-frontend","title":"Setting up the frontend","text":""},{"location":"API-and-Development/Development-Setup/#-install-nodejs-dependencies","title":"- Install node.js dependencies","text":"
    cd frontend\n# npm version >= 9 needed\nnpm install\n
    "},{"location":"API-and-Development/Development-Setup/#-create-symlink-to-library-and-resources","title":"- Create symlink to library and resources","text":"
    mkdir assets/romm\nln -s ../romm_mock/resources assets/romm/resources\nln -s ../romm_mock/assets assets/romm/assets\n
    "},{"location":"API-and-Development/Development-Setup/#-run-the-frontend","title":"- Run the frontend","text":"
    npm run dev\n
    "},{"location":"API-and-Development/Development-Setup/#setting-up-the-linter","title":"Setting up the linter","text":"

    We use Trunk for linting, which combines multiple linters and formatters with sensible defaults and a single configuration file. You'll need to install the Trunk CLI to use it.

    "},{"location":"API-and-Development/Development-Setup/#-install-the-trunk-cli","title":"- Install the Trunk CLI","text":"
    curl https://get.trunk.io -fsSL | bash\n

    Alternative installation methods can be found in their docs. On commit, the linter will run automatically. To run it manually, use the following commands:

    trunk fmt\ntrunk check\n

    Failing to install and run the linter will result in a failed CI check, which won't allow us to merge your PR.

    "},{"location":"API-and-Development/Development-Setup/#test-setup","title":"Test setup","text":""},{"location":"API-and-Development/Development-Setup/#-create-the-test-user-and-database-with-root-user","title":"- Create the test user and database with root user","text":"
    docker exec -i romm-db-dev mariadb -uroot -p<root password> < backend/romm_test/setup.sql\n
    "},{"location":"API-and-Development/Development-Setup/#-run-tests","title":"- Run tests","text":"

    Migrations will be run automatically when running the tests.

    cd backend\n# path or test file can be passed as argument to test only a subset\nuv run pytest [path/file]\n# or run the following command to run all tests\n# the -vv switch increases the verbosity of the output, providing more detailed information during test execution.\nuv run pytest -vv\n
    "},{"location":"Getting-Started/Authentication/","title":"Authentication","text":"

    RomM provides support for various forms of authentication, granting flexibility in securing access to its features.

    "},{"location":"Getting-Started/Authentication/#setup","title":"Setup","text":"

    You'll want to set the following environment variable before starting RomM:

    "},{"location":"Getting-Started/Authentication/#sessions","title":"Sessions","text":"

    When the /login endpoint is called with valid credentials, a session_id is generated, stored as a cookie and sent to the browser. The same token is used to create a cache entry in Valkey (or in-memory if Valkey is disabled) which maps the token to the user. This way no sensitive information is stored on the client.

    "},{"location":"Getting-Started/Authentication/#roles","title":"Roles","text":"

    A user can have one of the following roles:

    As permissions are additive, editors will have all permissions of the viewer role, and admins all those of the editor role.

    "},{"location":"Getting-Started/Authentication/#basic-authentication","title":"Basic Authentication","text":"

    Requests can be made to protected API endpoints with an authorization header. The token is the base64 encoded value of username:password.

    Example using cURL:

    curl https://romm.local/api/platforms -H 'Authorization: Basic YWRtaW46aHVudGVyMg=='\n
    "},{"location":"Getting-Started/Authentication/#oauth","title":"OAuth","text":"

    Along with the above forms of authentication, we've added an endpoint to generate expiring, scope-limited authentication tokens (/api/token). Successfully authenticating with that endpoint with return an access_token valid for 15 minutes, and a refresh_token valid for 2 weeks. The refresh_token can be used to generate a new access_token when needed.

    The /api/token endpoint requires a username, password, and a list of scopes in the format read:roms write:roms read:platforms .... The list of scopes and endpoints are available to browse via Swagger UI or ReDoc (see next section).

    Note: As of now, only the legacy password grant type is supported. We plan to eventually add support for Client Credentials.

    "},{"location":"Getting-Started/Authentication/#openapi","title":"OpenAPI","text":"

    The API endpoints are fully documented and compliant with the OpenAPI specification. Explore the API endpoints using the Swagger UI interface at /api/docs and the ReDoc interface at /api/redoc, or view the raw JSON at /openapi.json.

    For more information on OpenAPI, visit the OpenAPI Specification website.

    "},{"location":"Getting-Started/Authentication/#faq","title":"FAQ","text":""},{"location":"Getting-Started/Authentication/#can-i-disable-authentication","title":"Can I disable authentication?","text":"

    No, authentication is required and enabled by default.

    "},{"location":"Getting-Started/Authentication/#i-want-to-allow-an-editor-to-edit-roms-but-not-delete-them-can-i-do-that","title":"I want to allow an EDITOR to edit ROMs but not delete them. Can I do that?","text":"

    At this time, fine-grain control over permissions within a role is not supported. This decision was taking in order to simplify user management in the client, and authentication/permission code on the server.

    "},{"location":"Getting-Started/Authentication/#is-authentication-saferobust-can-i-trust-it","title":"Is authentication safe/robust? Can I trust it?","text":"

    We've done our best to build an authentication system that is simple, clear and comprehensible. We have automated tests which verify that access is granted when it should be, and blocked when not (invalid credentials, missing permissions, expired access tokens, etc.). That being said, we welcome any reviews of our authentication and permission flows, PRs to fix issues, and new tests to cover edge cases.

    "},{"location":"Getting-Started/Authentication/#i-found-an-bugissue-with-authentication-how-do-i-report-it","title":"I found an bug/issue with authentication. How do I report it?","text":"

    Please report bugs in our authentication/permission system privately by submitting a vulnerability report.

    "},{"location":"Getting-Started/Configuration-File/","title":"Configuration File","text":"

    Below is a breakdown of each section of the config.yml file and its purpose. You can find a full example of the file in the config.example.yml file.

    "},{"location":"Getting-Started/Configuration-File/#exclude-section","title":"Exclude Section","text":"

    Control which platforms, ROMs, or files to ignore during scanning.

    "},{"location":"Getting-Started/Configuration-File/#platforms","title":"Platforms","text":"

    Exclude entire platforms (folders) from being scanned.

    exclude:\n    platforms: [\"ps\", \"ngc\", \"gba\"]\n
    "},{"location":"Getting-Started/Configuration-File/#roms","title":"ROMs","text":"

    Fine-tune which ROMs or files are excluded.

    "},{"location":"Getting-Started/Configuration-File/#single-file-roms","title":"Single File ROMs","text":"

    Applies to ROMs that are single files (not in subfolders).

    exclude:\n    roms:\n        single_file:\n            extensions: [\"xml\", \"txt\"]\n            names: [\"info.txt\", \"._*\", \"*.nfo\"]\n
    "},{"location":"Getting-Started/Configuration-File/#multi-file-roms","title":"Multi-File ROMs","text":"

    Applies to ROMs stored as folders (multi-disc, with DLC, etc.).

    exclude:\n    roms:\n        multi_file:\n            names: [\"final fantasy VII\", \"DLC\"]\n            parts:\n                names: [\"data.xml\", \"._*\"]\n                extensions: [\"xml\", \"txt\"]\n
    "},{"location":"Getting-Started/Configuration-File/#system-section","title":"System Section","text":"

    Customize how RomM interprets your folder and platform names.

    "},{"location":"Getting-Started/Configuration-File/#custom-folder-names","title":"Custom Folder Names","text":"

    Map your custom folder names to RomM's recognized platform names.

    system:\n    platforms:\n        gc: \"ngc\" # Treats 'gc' folder as GameCube\n        psx: \"ps\" # Treats 'psx' folder as PlayStation\n
    "},{"location":"Getting-Started/Configuration-File/#versions","title":"Versions","text":"

    Associate a platform with its main version. This also tells RomM to fetch metadata from the main version source.

    system:\n    versions:\n        naomi: \"arcade\"\n
    "},{"location":"Getting-Started/Configuration-File/#filesystem-section","title":"Filesystem Section","text":"

    Specify the folder name where your ROMs are located if it differs from the default.

    If your ROMs folder is named my_roms instead of roms:

    filesystem:\n    roms_folder: \"my_roms\"\n

    Disable file hash calculation for low power devices (e.g. Raspberry PI).

    filesystem:\n    skip_hash_calculation: true\n
    "},{"location":"Getting-Started/Configuration-File/#scan-section","title":"Scan Section","text":"

    Configure metadata scanning priorities and media assets to download.

    "},{"location":"Getting-Started/Configuration-File/#priority","title":"Priority","text":"

    Customize the order in which metadata providers are queried during scans.

    "},{"location":"Getting-Started/Configuration-File/#metadata","title":"Metadata","text":"

    Controls metadata provider priority order.

    Provider list in default order:

    scan:\n    priority:\n        metadata:\n            - \"igdb\"\n            - \"ss\"\n            - \"moby\"\n
    "},{"location":"Getting-Started/Configuration-File/#artwork","title":"Artwork","text":"

    Controls artwork provider priority order for cover art and screenshots.

    Default: Same as priority.metadata

    scan:\n    priority:\n        artwork:\n            - \"igdb\"\n            - \"ss\"\n            - \"moby\"\n
    "},{"location":"Getting-Started/Configuration-File/#region","title":"Region","text":"

    Sets preferred region for cover art and game title (Screenscraper only).

    Default: [\"us\", \"wor\", \"ss\", \"eu\", \"jp\"]

    scan:\n    priority:\n        region:\n            - \"us\"\n            - \"eu\"\n            - \"jp\"\n
    "},{"location":"Getting-Started/Configuration-File/#language","title":"Language","text":"

    Sets preferred language for cover art and game title (Screenscraper only).

    Default: [\"en\", \"fr\"]

    scan:\n    priority:\n        language:\n            - \"en\"\n            - \"es\"\n            - \"fr\"\n
    "},{"location":"Getting-Started/Configuration-File/#media","title":"Media","text":"

    Configures which media assets to download (Screenscraper and ES-DE gamelist.xml only).

    Media types:

    scan:\n    media:\n        - box2d\n        - screenshot\n        - manual\n        - bezel\n
    "},{"location":"Getting-Started/Configuration-File/#emulatorjs-section","title":"EmulatorJS Section","text":"

    Configure EmulatorJS per-core options and controls.

    "},{"location":"Getting-Started/Configuration-File/#debug","title":"Debug","text":"

    Enable debug mode to log available options to the browser console.

    emulatorjs:\n    debug: true\n
    "},{"location":"Getting-Started/Configuration-File/#cache-limit","title":"Cache Limit","text":"

    Cache limit per ROM in bytes. Set to null for unlimited.

    emulatorjs:\n    cache_limit: 52428800 # 50 MB\n
    "},{"location":"Getting-Started/Configuration-File/#disable-batch-bootup","title":"Disable batch bootup","text":"

    Skips the step that runs a batch file that sets soundcard information, mounts file systems, and attempts to run an autorun.bat file (try this if DOS games fail to boot).

    emulatorjs:\n    disable_batch_bootup: true\n
    "},{"location":"Getting-Started/Configuration-File/#disable-auto-unload","title":"Disable auto-unload","text":"

    The emulator stops/shuts itself down when you navigate to a new page; this setting stops that behaviour (if that's something you want).

    emulatorjs:\n    disable_auto_unload: true\n
    "},{"location":"Getting-Started/Configuration-File/#netplay","title":"Netplay","text":"

    Enable netplay and configure STUN/TURN servers. We recommend Google's public servers or Metered's free tier.

    emulatorjs:\n    netplay:\n        enabled: true\n        ice_servers:\n            - urls: \"stun:stun.l.google.com:19302\"\n            - urls: \"stun:stun1.l.google.com:19302\"\n            - urls: \"stun:stun2.l.google.com:19302\"\n            - urls: \"turn:openrelay.metered.ca:80\"\n              username: \"openrelayproject\"\n              credential: \"openrelayproject\"\n            - urls: \"turn:openrelay.metered.ca:443\"\n              username: \"openrelayproject\"\n              credential: \"openrelayproject\"\n
    "},{"location":"Getting-Started/Configuration-File/#settings","title":"Settings","text":"

    Configure core-specific settings. Use default to apply settings to all cores.

    emulatorjs:\n    settings:\n        parallel_n64: # Use the exact core name\n            vsync: disable\n        snes9x:\n            snes9x_region: ntsc\n        default: # These settings apply to all cores\n            fps: show\n
    "},{"location":"Getting-Started/Configuration-File/#controls","title":"Controls","text":"

    Map keyboard and controller controls for each player.

    Example (2-player SNES):

    emulatorjs:\n    controls:\n        snes9x:\n            0: # Player 1\n                0: # Button mapping\n                    value: x # Keyboard mapping\n                    value2: BUTTON_2 # Controller mapping\n            1: # Player 2\n                0:\n                    value: /\n                    value2: BUTTON_2\n

    See EmulatorJS documentation for control mapping details.

    Tip

    You can find examples of full binded batocera or es-de config files.

    Warning

    Only uncomment or add the lines you need. Any omitted or empty sections will use RomM's defaults.

    For a full example, see the config.example.yml file.

    "},{"location":"Getting-Started/Environment-Variables/","title":"Environment Variables","text":"

    This is a complete list of available environment variables; required variables are marked with a \u2713.

    Tip

    You can also set environment variables with a _FILE suffix, which will load the contents of the file specified in the variable into the variable without the suffix. For example, setting ROMM_AUTH_SECRET_KEY_FILE=/run/secrets/romm_auth_secret_key and creating a file with the secret key at the specified path will set ROMM_AUTH_SECRET_KEY to the contents of the file. Learn more.

    "},{"location":"Getting-Started/Environment-Variables/#application-settings","title":"Application settings","text":"Variable Description Required Default ROMM_AUTH_SECRET_KEY Generate a key with openssl rand -hex 32 \u2713 DISABLE_CSRF_PROTECTION Disables CSRF protection (not recommended) false DISABLE_DOWNLOAD_ENDPOINT_AUTH Disable auth on download endpoint (WebRcade, Tinfoil) false DISABLE_USERPASS_LOGIN Disables login with username and password (when using OIDC) false SESSION_MAX_AGE_SECONDS Maximum age of a session (in seconds) 1209600 (14 days) KIOSK_MODE Read-only mode for public displays or kiosks false UPLOAD_TIMEOUT Timeout for file uploads (in seconds) 600 (10 minutes) SCAN_TIMEOUT Timeout for the background scan/rescan tasks (in seconds) 14400 (4 hours) SCAN_WORKERS Number of worker processes for scanning tasks 1 TASK_TIMEOUT Timeout for the the rest of the background tasks (in seconds) 300 (5 minutes) TASK_RESULT_TTL How long to keep task results in Valkey (in seconds) 86400 (24 hours) SEVEN_ZIP_TIMEOUT Timeout for 7-Zip operations (in seconds) 60 DISABLE_EMULATOR_JS Disables playing in browser with EmulatorJS false DISABLE_RUFFLE_RS Disables playing flash games with RuffleRS false YOUTUBE_BASE_URL Base URL for alternate frontends (Piped, Invidious, etc.) https://www.youtube.com TZ Sets the timezone UTC ROMM_PORT Port on which the application listens 8080 ROMM_BASE_PATH Base folder path for library, resources and assets /romm ROMM_BASE_URL Base url for properly display container logs links (like register or recover password) 0.0.0.0 LOGLEVEL Logging level for the app INFO FORCE_COLOR Forces color output false NO_COLOR Disables color output false WEB_SERVER_CONCURRENCY Number of processes running the app 1 WEB_SERVER_KEEPALIVE Waiting time for requests on a Keep-Alive connection (in seconds) 2 WEB_SERVER_MAX_REQUESTS Maximum number of requests a worker will process before restarting 1000 WEB_SERVER_MAX_REQUESTS_JITTER Random jitter to add to the maximum number of requests a worker will process before restarting 100 WEB_SERVER_TIMEOUT Timeout for web server requests (in seconds) 300 WEB_SERVER_WORKER_CONNECTIONS Maximum number of simultaneous clients a single process can handle 1000"},{"location":"Getting-Started/Environment-Variables/#dependencies","title":"Dependencies","text":"Variable Description Required Default DB_HOST Host name of database instance \u2713 DB_PORT Port number of database instance 3306 DB_NAME Should match MYSQL_DATABASE in MariaDB romm DB_USER Database username (in MariaDB, should match MARIADB_USER) \u2713 DB_PASSWD Database password (in MariaDB, should match MARIADB_PASSWORD) \u2713 DB_QUERY_JSON Extra query parameters for the database connection, in JSON format (e.g. {\"unix_socket\": \"/path/to/db\"}) ROMM_DB_DRIVER Database driver to use (options: mariadb, mysql, postgresql) mariadb REDIS_HOST Host name of Redis/Valkey instance 127.0.0.1 REDIS_PORT Port number of Redis/Valkey instance 6379 REDIS_USERNAME Username for Redis/Valkey instance REDIS_PASSWORD Password for Redis/Valkey instance REDIS_DB Database number for Redis/Valkey instance 0 REDIS_SSL Enable SSL for Redis/Valkey instance false SENTRY_DSN DSN for Sentry error tracking"},{"location":"Getting-Started/Environment-Variables/#metadata-providers","title":"Metadata providers","text":"Variable Description Required Default IGDB_CLIENT_ID Client ID for IGDB API IGDB_CLIENT_SECRET Client secret for IGDB API SCREENSCRAPER_USER Screenscraper username SCREENSCRAPER_PASSWORD Screenscraper password MOBYGAMES_API_KEY MobyGames secret API key STEAMGRIDDB_API_KEY SteamGridDB secret API key RETROACHIEVEMENTS_API_KEY Retroachievements secret API key REFRESH_RETROACHIEVEMENTS_CACHE_DAYS Retroachievements metadata cache refresh (in days) 30 LAUNCHBOX_API_ENABLED Enable LaunchBox API integration false PLAYMATCH_API_ENABLED Enable PlayMatch API integration false HASHEOUS_API_ENABLED Enable Hasheous API integration false FLASHPOINT_API_ENABLED Enable Flashpoint API integration false HLTB_API_ENABLED Enable HowLongToBeat API integration false"},{"location":"Getting-Started/Environment-Variables/#authentication","title":"Authentication","text":"Variable Description Required Default OIDC_ENABLED Enable OpenID Connect (OIDC) authentication false OIDC_PROVIDER Name of the OIDC provider in use OIDC_CLIENT_ID Client ID for OIDC authentication OIDC_CLIENT_SECRET Client secret for OIDC authentication OIDC_REDIRECT_URI Absolute redirect URI for OIDC authentication OIDC_SERVER_APPLICATION_URL Absolute URL of the OIDC server application OIDC_TLS_CACERTFILE Path to a file containing trusted CA certificates OIDC_USERNAME_ATTRIBUTE Attribute on OIDC user info used as the username preferred_username"},{"location":"Getting-Started/Environment-Variables/#background-tasks","title":"Background tasks","text":"Variable Description Required Default ENABLE_RESCAN_ON_FILESYSTEM_CHANGE Enable re-scanning of library when filesystem changes false RESCAN_ON_FILESYSTEM_CHANGE_DELAY Delay before re-scanning library when filesystem changes (in minutes) 5 ENABLE_SCHEDULED_RESCAN Enable scheduled re-scanning of library false SCHEDULED_RESCAN_CRON Cron expression for scheduled re-scanning \"0 3 * * *\" ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB Enable scheduled updating of Switch TitleDB index false SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON Cron expression for scheduled updating of Switch TitleDB \"0 4 * * *\" ENABLE_SCHEDULED_UPDATE_LAUNCHBOX_METADATA Enable scheduled updating of LaunchBox metadata false SCHEDULED_UPDATE_LAUNCHBOX_METADATA_CRON Cron expression for scheduled updating of LaunchBox metadata \"0 4 * * *\" ENABLE_SCHEDULED_CONVERT_IMAGES_TO_WEBP Enable scheduled conversion of images to WebP format false SCHEDULED_CONVERT_IMAGES_TO_WEBP_CRON Cron expression for scheduled conversion of images to WebP format \"0 4 * * *\" ENABLE_SCHEDULED_RETROACHIEVEMENTS_PROGRESS_SYNC Enable scheduled syncing of Retroachievements progress false SCHEDULED_RETROACHIEVEMENTS_PROGRESS_SYNC_CRON Cron expression for scheduled syncing of Retroachievements progress \"0 4 * * *\""},{"location":"Getting-Started/Environment-Variables/#development","title":"Development","text":"Variable Description Required Default DEV_MODE Enable development mode (debugging, hot-reloading) false DEV_HOST Host for development server 127.0.0.1 DEV_PORT Port for development server 5000 DEV_SQL_ECHO Enable SQL query logging in development mode false"},{"location":"Getting-Started/Folder-Structure/","title":"Folder Structure","text":"

    RomM requires one of these folder structures for proper operation. It will first attempt to detect Structure A (recommended), and if not found, will fall back to Structure B. This auto-detection ensures flexibility while encouraging organization best practices.

    "},{"location":"Getting-Started/Folder-Structure/#folder-organization","title":"Folder Organization","text":"

    RomM organizes content in two main categories: ROMs and BIOS files.

    Note

    The BIOS folder is entirely optional and only needed for platforms that require BIOS files.

    When using Docker, the volume mount point differs based on your chosen structure:

    For multifile games (games stored as folders with multiple files or folders inside), RomM will detect special folders inside the game and will display with special tags in the webUI:

    Tip

    For folder naming conventions, review the Platform Support section. To override default system names in the folder structure (if your directories are named differently), see the Configuration File section.

    Structure A (recommended) Structure B (fallback) library/roms/{platform}/{game} library/{platform}/roms/{game}
    \n        library/\n        \u251c\u2500 roms/\n        \u2502  \u251c\u2500 gbc/\n        \u2502  \u2502  \u251c\u2500 game_1.gbc\n        \u2502  \u2502  \u2514\u2500 game_2.gbc\n        \u2502  \u2502\n        \u2502  \u251c\u2500 gba/\n        \u2502  \u2502  \u251c\u2500 game_3.gba\n        \u2502  \u2502  \u2514\u2500 game_4/\n        \u2502  \u2502     \u251c\u2500 game_4.gba\n        \u2502  \u2502     \u251c\u2500 dlc\n        \u2502  \u2502     \u2502  \u251c\u2500 game_4_dlc_1.7z\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_dlc_2.7z\n        \u2502  \u2502     \u251c\u2500 hack\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_hardmode.rar\n        \u2502  \u2502     \u251c\u2500 manual\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_manual.pdf\n        \u2502  \u2502     \u251c\u2500 mod\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_crazy_mode.zip\n        \u2502  \u2502     \u251c\u2500 patch\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_patch_v1.1.zip\n        \u2502  \u2502     \u251c\u2500 update\n        \u2502  \u2502     \u251c\u2500 demo\n        \u2502  \u2502     \u251c\u2500 translation\n        \u2502  \u2502     \u2514\u2500 prototype\n        \u2502  \u2502\n        \u2502  \u2514\u2500 ps/\n        \u2502     \u251c\u2500 game_5/\n        \u2502     \u2502   \u251c\u2500 game_5_cd_1.iso\n        \u2502     \u2502   \u2514\u2500 game_5_cd_2.iso\n        \u2502     \u2502\n        \u2502     \u2514\u2500 game_6.iso\n        \u2502\n        \u2514\u2500 bios/\n           \u251c\u2500 gba/\n           \u2502  \u2514\u2500 gba_bios.bin\n           \u2502\n           \u2514\u2500 ps/\n              \u251c\u2500 scph1001.bin\n              \u251c\u2500 scph5501.bin\n              \u2514\u2500 scph5502.bin\n      
    \n        library/\n        \u251c\u2500 gbc/\n        \u2502  \u2514\u2500 roms/\n        \u2502     \u251c\u2500 game_1.gbc\n        \u2502     \u2514\u2500 game_2.gbc\n        \u2502\n        \u251c\u2500 gba/\n        \u2502  \u251c\u2500 roms/\n        \u2502  \u2502  \u251c\u2500 game_3.gba\n        \u2502  \u2502  \u2514\u2500 game_4/\n        \u2502  \u2502     \u251c\u2500 game_4.gba\n        \u2502  \u2502     \u251c\u2500 dlc\n        \u2502  \u2502     \u2502  \u251c\u2500 game_4_dlc_1.7z\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_dlc_2.7z\n        \u2502  \u2502     \u251c\u2500 hack\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_hardmode.rar\n        \u2502  \u2502     \u251c\u2500 manual\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_manual.pdf\n        \u2502  \u2502     \u251c\u2500 mod\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_crazy_mode.zip\n        \u2502  \u2502     \u251c\u2500 patch\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_patch_v1.1.zip\n        \u2502  \u2502     \u251c\u2500 update\n        \u2502  \u2502     \u251c\u2500 demo\n        \u2502  \u2502     \u251c\u2500 translation\n        \u2502  \u2502     \u2514\u2500 prototype\n        \u2502  \u2502\n        \u2502  \u2514\u2500 bios/\n        \u2502     \u2514\u2500 gba_bios.bin\n        \u2502\n        \u2514\u2500 ps/\n           \u251c\u2500 roms/\n           \u2502  \u251c\u2500 game_5/\n           \u2502  \u2502  \u251c\u2500 game_5_cd_1.iso\n           \u2502  \u2502  \u2514\u2500 game_5_cd_2.iso\n           \u2502  \u2502\n           \u2502  \u2514\u2500 game_6.iso\n           \u2502\n           \u2514\u2500 bios/\n              \u251c\u2500 scph1001.bin\n              \u251c\u2500 scph5501.bin\n              \u2514\u2500 scph5502.bin\n      

    Note

    RomM can be setup without a prior folder structure. If files are manually uploaded from the webUI, RomM will automatically create the folder Structure A

    "},{"location":"Getting-Started/Folder-Structure/#configuration-file","title":"Configuration file","text":"

    RomM's behavior can be customized using a config.yml file or through the Library Management page in the Settings menu. You can grab the example config.example.yml file and adapt it to your library.

    What is shown in the Library Management page is the content of the config.yml. For more details read the configuration file section.

    "},{"location":"Getting-Started/Folder-Structure/#naming-convention","title":"Naming Convention","text":""},{"location":"Getting-Started/Folder-Structure/#tag-support","title":"Tag Support","text":"

    Games can be tagged with region, revision, or other tags by using parentheses in the file name. RomM will parse both tags with [] and ().

    Tags can be used to search for games in the search bar. For example, searching for (USA) will return all games with the USA tag.

    #### Supported Languages The following language tags are recognized by RomM: | Code | Language | | ------ | ----------- | | Ar | Arabic | | Da | Danish | | De | German | | El | Greek | | En | English | | Es | Spanish | | Fi | Finnish | | Fr | French | | It | Italian | | Ja | Japanese | | Ko | Korean | | Nl | Dutch | | No | Norwegian | | Pl | Polish | | Pt | Portuguese | | Ru | Russian | | Sr | Serbian | | Sv | Swedish | | Zh | Chinese | | nolang | No Language | #### Supported Regions The following region tags are recognized by RomM: | Code | Region | | ---- | ------------- | | A | Australia | | AS | Asia | | B | Brazil | | C | Canada | | CH | China | | E | Europe | | F | France | | FN | Finland | | G | Germany | | GR | Greece | | H | Holland | | HK | Hong Kong | | I | Italy | | J | Japan | | K | Korea | | NL | Netherlands | | NO | Norway | | PD | Public Domain | | R | Russia | | S | Spain | | SW | Sweden | | T | Taiwan | | U | USA | | UK | England | | UNK | Unknown | | UNL | Unlicensed | | W | World |"},{"location":"Getting-Started/Metadata-Providers/","title":"Metadata Providers","text":"

    RomM supports multiple metadata providers to enrich your game library with titles, descriptions, cover art, and achievements. You don't need all providers, so this guide covers popular combos and setup instructions.

    "},{"location":"Getting-Started/Metadata-Providers/#popular-combos","title":"Popular combos","text":"

    Here are some combinations you can use based on your needs:

    "},{"location":"Getting-Started/Metadata-Providers/#the-french-connection-screenscraper-retroachievements","title":"\u2b50 The French Connection: ScreenScraper + Retroachievements","text":""},{"location":"Getting-Started/Metadata-Providers/#the-chefs-choice-hasheous-igdb-steamgriddb-retroachievements","title":"\u2b50 The Chef's Choice: Hasheous + IGDB + SteamGridDB + Retroachievements","text":""},{"location":"Getting-Started/Metadata-Providers/#the-twitch-fanboy-igdb-playmatch","title":"The Twitch Fanboy: IGDB + PlayMatch","text":""},{"location":"Getting-Started/Metadata-Providers/#the-quick-starter-hasheous","title":"The Quick Starter: Hasheous","text":""},{"location":"Getting-Started/Metadata-Providers/#setup-instructions","title":"Setup instructions","text":""},{"location":"Getting-Started/Metadata-Providers/#igdb","title":"IGDB","text":"

    IGDB (Internet Game Database) is a popular metadata provider that offers metadata, cover art, screenshots, related games and more.

    To access the IGDB API you'll need a Twitch account and a valid phone number for 2FA verification. Up-to-date instructions are available in the IGDB API documentation. When registering your application in the Twitch Developer Portal, fill out the form like so:

    Important

    The name you pick has to be unique! Picking an existing name will fail silently, with no error messages. We recommend using romm-<random hash>, like romm-3fca6fd7f94dea4a05d029f654c0c44b

    Note the client ID and secret that appear on screen, and use them to set IGDB_CLIENT_ID and IGDB_CLIENT_SECRET in your environment variables.

    Screenshots

    "},{"location":"Getting-Started/Metadata-Providers/#screenscraper","title":"ScreenScraper","text":"

    ScreenScraper.fr is a French provider that offers metadata, cover art, screenshots and manuals, along with the option for 3D boxes and CD/cartridge cover art. It supports a wide range of systems and is a great alternative to IGDB.

    To access the ScreenScraper API, create a ScreenScraper account and copy the user and password you just created to SCREENSCRAPER_USER and SCREENSCRAPER_PASSWORD respectively.

    "},{"location":"Getting-Started/Metadata-Providers/#mobygames","title":"MobyGames","text":"

    MobyGames is a metadata provider that offers metadata, cover art and screenshots.

    To access the MobyGames API, create a MobyGames account and then visit your profile page. Click the API link under your user name to sign up for an API key. Copy the key shown and use it to set MOBYGAMES_API_KEY.

    Important

    Access to the MobyGames API is a paid feature. While we will continue to support it, we recommend using ScreenScraper instead, as it is free to use.

    "},{"location":"Getting-Started/Metadata-Providers/#launchbox","title":"LaunchBox","text":"

    The LaunchBox Games Database is a community-driven database that provides metadata, cover art, and screenshots. Like the Launchbox desktop application, RomM downloads the entire database locally and matches games based on their exact filenames.

    To enable LaunchBox, set LAUNCHBOX_API_ENABLED=true in your environment variables. You can enable regular updates of the database by setting ENABLE_SCHEDULED_UPDATE_LAUNCHBOX_METADATA, and set the frequency on the cron job with SCHEDULED_UPDATE_LAUNCHBOX_METADATA_CRON (defaults to 5:00 AM every day).

    "},{"location":"Getting-Started/Metadata-Providers/#hasheous","title":"Hasheous","text":"

    Hasheous is a free, open-source metadata provider that uses file hashes to match games. It proxies IGDB data for titles, descriptions, and cover art, and can provide Retroachievements IDs for matched games.

    Simply set HASHEOUS_API_ENABLED=true in your environment variables, and future scans will start using the Hasheous API.

    "},{"location":"Getting-Started/Metadata-Providers/#playmatch","title":"PlayMatch","text":"

    PlayMatch is a hash-based matching service used in conjunction with IGDB to provide better matching for games, hosted by a member of our community.

    To enable PlayMatch, set PLAYMATCH_API_ENABLED=true in your environment variables.

    "},{"location":"Getting-Started/Metadata-Providers/#steamgriddb","title":"SteamGridDB","text":"

    SteamGridDB provides custom cover art for games or collections. It's not accessed through the scanner but from the \"search cover\" button when manually editing a game.

    To access the SteamGridDB API, you need to login to their website with a Steam account. Once logged in, go to your API tab under the preferences page. Copy the key shown and use it to set STEAMGRIDDB_API_KEY.

    "},{"location":"Getting-Started/Metadata-Providers/#retroachievements","title":"RetroAchievements","text":"

    RomM is able to display your achievements from RetroAchievements. To sync it with your RomM instance, you need to generate an API key from your RetroAchievements account in your settings.

    Copy the key shown and use it to set RETROACHIEVEMENTS_API_KEY and perform a UNMATCHED scan targeting the platform you want to match with RetroAchievements.

    After that, each user needs to set their own username in their profile and sync it with RetroAchievements. A new Achievements tab will appear in the Personal tab in the game details.

    To avoid unnecessary API calls, a cached file with the RA database is stored in RomM. Refresh time for that cache file can be changed with the environment variable REFRESH_RETROACHIEVEMENTS_CACHE_DAYS.

    Screenshots

    "},{"location":"Getting-Started/Metadata-Providers/#flashpoint","title":"Flashpoint","text":"

    The Flashpoint Project Database is a project that enables metadata for 180,000+ flash and browser-based games. Enable this metadata source with the FLASHPOINT_API_ENABLED=true environment variable. If you are adding this provider to an existing RomM setup, perform a UNMATCHED scan with Flashpoint selected to update an existing platform.

    "},{"location":"Getting-Started/Metadata-Providers/#how-long-to-beat","title":"How Long To Beat","text":"

    The How Long To Beat project provides game completion times for more than 84,000 games. Enable this metadata source with the HLTB_API_ENABLED=true environment variable. If you are adding this provider to an existing RomM setup, perform a UNMATCHED scan with How Long To Beat selected to update an existing platform.

    Game completion times will be added to a new tab on the details page for supported matched games.

    "},{"location":"Getting-Started/Metadata-Providers/#es-de-gamelistxml","title":"ES-DE gamelist.xml","text":"

    EmulationStation, and it's modern successor ES-DE, use a custom XML format to store game metadata. RomM can parse this format and import the assets as cover art and screenshots. You'll need to store the gamelist.xml file and any related assets under the platform folder:

    library/\n\u2514\u2500 roms/\n    \u2514\u2500 gba/\n        \u251c\u2500 game_1.gba\n        \u251c\u2500 game_2.gba\n        \u251c\u2500 gamelist.xml\n        \u251c\u2500 3dboxes/\n        \u2502  \u251c\u2500 game_1.png\n        \u2502  \u2514\u2500 game_2.png\n        \u251c\u2500 covers/\n        \u251c\u2500 screenshots/\n        \u2514\u2500 etc...\n
    "},{"location":"Getting-Started/Metadata-Providers/#es-de-settings","title":"ES-DE settings","text":"

    Here are the settings you need to change so RomM can read your artwork and gamelist.xml files from the same folder that holds your ROMs.

    1. Open the ES-DE settings file:

    2. Make these two edits (add the lines if they don\u2019t exist):

      <string name=\"MediaDirectory\" value=\"/path/to/ROMs/folder\" />\n<bool name=\"LegacyGamelistFileLocation\" value=\"true\" />\n
    3. If you already have scraped artwork, copy/move the systems from ~/ES-DE/downloaded_media/ and ~/ES-DE/gamelists/ into your ROMs folder

    After a restart, ES-DE will place new artwork and the updated gamelist.xml directly in roms/<system>/, which is the layout RomM expects.

    "},{"location":"Getting-Started/Metadata-Providers/#metadata-tags-in-filenames","title":"Metadata Tags in Filenames","text":"

    Scans will now parse custom metadata tags in the filename that match specific patterns, and use them to fetch game metadata for the specified ID. The supported tags are:

    (igdb-xxxx) for IGDB (moby-xxxx) for MobyGames (ra-xxxx) for RetroAchievements (ssfr-xxxx) for ScreenScraper (launchbox-xxxx) for Launchbox (hltb-xxxx) for HowLongToBeat

    Filenames will not be renamed by RomM to add tags, as they are a non-standard formatting system and could create conflicts with other software.

    "},{"location":"Getting-Started/OIDC-Setup/","title":"OIDC Setup","text":""},{"location":"Getting-Started/OIDC-Setup/#oidc-setup","title":"OIDC Setup","text":"

    OpenID Connect (OIDC) allows you to authenticate to RomM using external identity providers, enabling Single Sign-On (SSO) and centralized user management. This setup eliminates the need to manage separate credentials for RomM.

    "},{"location":"Getting-Started/OIDC-Setup/#what-is-oidc","title":"What is OIDC?","text":"

    OIDC is an identity layer built on top of OAuth2. While OAuth2 primarily handles authorization, OIDC adds authentication, enabling applications to verify a user's identity and obtain profile information. This makes OIDC suitable for SSO solutions, where user identity is central to access management.

    "},{"location":"Getting-Started/OIDC-Setup/#how-it-works","title":"How It Works","text":"
    1. Click the OIDC login button on RomM's login page
    2. You're redirected to your identity provider
    3. Authenticate with your credentials
    4. You're redirected back to RomM and logged in automatically
    "},{"location":"Getting-Started/OIDC-Setup/#supported-identity-providers","title":"Supported Identity Providers","text":"

    RomM supports OIDC authentication with the following identity providers:

    "},{"location":"Getting-Started/OIDC-Setup/#authelia","title":"Authelia","text":"

    An open-source authentication and authorization server providing two-factor authentication and SSO. Ideal for self-hosters looking for a lightweight solution.

    "},{"location":"Getting-Started/OIDC-Setup/#authentik","title":"Authentik","text":"

    An open-source identity provider with support for modern authentication protocols, MFA, and comprehensive user management.

    "},{"location":"Getting-Started/OIDC-Setup/#pocketid","title":"PocketID","text":"

    A simple OIDC provider that exclusively supports passkey authentication - no passwords required.

    "},{"location":"Getting-Started/OIDC-Setup/#zitadel","title":"Zitadel","text":"

    An enterprise-grade, open-source identity and access management platform supporting OAuth2, OIDC, SAML, and passwordless authentication.

    "},{"location":"Getting-Started/OIDC-Setup/#general-setup-requirements","title":"General Setup Requirements","text":"

    Regardless of which provider you choose, you'll need to configure these environment variables in RomM:

    OIDC_ENABLED=true\nOIDC_PROVIDER=<provider_name>\nOIDC_CLIENT_ID=<your_client_id>\nOIDC_CLIENT_SECRET=<your_client_secret>\nOIDC_REDIRECT_URI=<your_romm_url>/api/oauth/openid\nOIDC_SERVER_APPLICATION_URL=<your_provider_url>\n
    "},{"location":"Getting-Started/OIDC-Setup/#important-notes","title":"Important Notes","text":""},{"location":"Getting-Started/OIDC-Setup/#troubleshooting","title":"Troubleshooting","text":"

    If you encounter issues with OIDC authentication:

    "},{"location":"Getting-Started/OIDC-Setup/#next-steps","title":"Next Steps","text":"

    Choose a provider from the list above and follow its specific setup guide. Each guide provides detailed step-by-step instructions for configuring both the identity provider and RomM.

    "},{"location":"Getting-Started/Quick-Start-Guide/","title":"Quick Start Guide","text":"

    This quick start guide will help you get a RomM instance up and running. It is split into 3 parts: Prepare, Build and Configure.

    "},{"location":"Getting-Started/Quick-Start-Guide/#prepare","title":"Prepare","text":"

    There are a few things you need to have in place before you can start:

    Warning

    RomM works without a metadata API for basic use, but may cause issues with plugins like Playnite. Setting up IGDB API keys is recommended to prevent setup problems.

    "},{"location":"Getting-Started/Quick-Start-Guide/#build","title":"Build","text":"

    Now that we have everything gathered, we can begin getting your instance set up!

    1. Download a copy of the latest docker-compose.example.yml file from GitHub
    2. Edit the file and modify the following values to configure the database
    3. Modify the following values in the environment to configure the application. -- Other values can be changed, but should not be done unless you know what you are doing, and are outside the scope of this guide
    4. Run the following command in a terminal and save the output to the ROMM_AUTH_SECRET_KEY environment variable:
      openssl rand -hex 32\n
      It should look something like this:
      03a054b6ca27e0107c5eed552ea66becd9f3a2a8a91e7595cd462a593f9ecd09\n
    5. Add your metadata sources API keys:
    6. Modify the following values in the volumes to configure the application
    7. Save the file as docker-compose.yml instead of docker-compose.example.yml. It should look something like this:

      Example Docker Compose
      version: \"3\"\n\nvolumes:\n    mysql_data:\n    romm_resources:\n    romm_redis_data:\n\nservices:\n    romm:\n        image: rommapp/romm:latest\n        container_name: romm\n        restart: unless-stopped\n        environment:\n            - DB_HOST=romm-db\n            - DB_NAME=romm # Should match MARIADB_DATABASE in mariadb\n            - DB_USER=romm-user # Should match MARIADB_USER in mariadb\n            - DB_PASSWD= # Should match MARIADB_PASSWORD in mariadb\n            - ROMM_AUTH_SECRET_KEY= # Generate a key with `openssl rand -hex 32`\n            - SCREENSCRAPER_USER= # These are the recommended metadata providers\n            - SCREENSCRAPER_PASSWORD= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#screenscraper\n            - RETROACHIEVEMENTS_API_KEY= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#retroachievements\n            - STEAMGRIDDB_API_KEY= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#steamgriddb\n            - HASHEOUS_API_ENABLED=true # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#hasheous\n        volumes:\n            - romm_resources:/romm/resources # Resources fetched from IGDB (covers, screenshots, etc.)\n            - romm_redis_data:/redis-data # Cached data for background tasks\n            - /path/to/library:/romm/library # Your game library. Check https://github.com/rommapp/romm?tab=readme-ov-file#folder-structure for more details.\n            - /path/to/assets:/romm/assets # Uploaded saves, states, etc.\n            - /path/to/config:/romm/config # Path where config.yml is stored\n        ports:\n            - 80:8080\n        depends_on:\n            romm-db:\n                condition: service_healthy\n                restart: true\n\n    romm-db:\n        image: mariadb:latest\n        container_name: romm-db\n        restart: unless-stopped\n        environment:\n            - MARIADB_ROOT_PASSWORD= # Use a unique, secure password\n            - MARIADB_DATABASE=romm\n            - MARIADB_USER=romm-user\n            - MARIADB_PASSWORD=\n        volumes:\n            - mysql_data:/var/lib/mysql\n        healthcheck:\n            test: [CMD, healthcheck.sh, --connect, --innodb_initialized]\n            start_period: 30s\n            start_interval: 10s\n            interval: 10s\n            timeout: 5s\n            retries: 5\n
    8. Open the terminal and navigate to the directory containing the docker-compose file

    9. Run docker compose up -d to kick off the docker pull. You will see it pull the container and set up the volumes and network:

          {\n        \"file\": \"../latest/resources/asciinema/quick-start-docker-compose.cast\",\n        \"title\": \"RomM docker compose install\",\n        \"preload\": true,\n        \"loop\": true,\n        \"auto_play\": true,\n        \"cols\": 140,\n        \"rows\": 30,\n        \"fit\": \"width\",\n        \"terminal_font_size\": \"small\",\n        \"terminal_line_height\": \"1.2\",\n        \"terminal_font_family\": \"Roboto Mono, Monaco, Consolas, monospace\"\n    }\n
    10. Run docker ps -f name=romm to verify that the containers are running

    11. Open a web browser and navigate to http://localhost:80, where you should be greeted with the RomM setup page
    12. Go through the setup wizard, setting your admin username and password
    13. Log in with the credentials you set in the last step
    "},{"location":"Getting-Started/Quick-Start-Guide/#configure","title":"Configure","text":""},{"location":"Getting-Started/Quick-Start-Guide/#importing-your-roms-via-scanner","title":"Importing your ROMs via scanner","text":"

    This method is generally the fastest and recommended for first time setup. You need your library properly mounted as a container volume:

    1. Log into RomM with your user credentials
    2. Click the Scan button in the sidebar
    3. Select the metadata providers you want to fetch metadata from
    4. The system will now begin scanning the ROM files and applying metadata to them. You can click on any of the items that it has tagged to see the metadata it pulled without having to stop the scan
    5. After the scan completes, click the RomM logo to go back to the main screen. You should see the platforms and recent games it has scanned. You are now ready to rock with RomM!
    "},{"location":"Getting-Started/Quick-Start-Guide/#uploading-your-roms-via-web-interface","title":"Uploading your ROMs via Web Interface","text":"

    This method is certainly viable, but not recommended if you have a lot of ROMs and/or multiple platforms. It is good for adding files after the fact as your collection grows, but wouldn't be recommended for the first setup, nor for multi-file ROMs:

    1. Log into RomM with your user credentials
    2. Click the Upload button in the sidebar
    3. Select the platform, then click + ADD and select the ROMs you want to upload in the file selector that appears
    4. Click Upload to begin uploading the ROMs
    5. Repeat for all the roms/platforms you have

    "},{"location":"Getting-Started/Reverse-Proxy/","title":"Reverse Proxy","text":"

    Here are some basic configurations for popular reverse proxies. Additional configuration may be required depending on your specific setup.

    "},{"location":"Getting-Started/Reverse-Proxy/#caddy","title":"Caddy","text":"
    http://romm.mysite.com {\n  reverse_proxy romm:8080\n}\n
    "},{"location":"Getting-Started/Reverse-Proxy/#caddy-tls-https","title":"Caddy + TLS (HTTPS)","text":"
    https://romm.mysite.com {\n  tls mysite.com.crt mysite.com.key  # Certificate and key files\n\n  encode zstd gzip\n\n  header * {\n    Strict-Transport-Security \"max-age=31536000;\"\n    X-XSS-Protection \"1; mode=block\"\n    X-Frame-Options \"SAMEORIGIN\"\n    X-Robots-Tag \"noindex, nofollow\"\n    -Server\n    -X-Powered-By\n  }\n\n  reverse_proxy romm:8080\n}\n
    "},{"location":"Getting-Started/Reverse-Proxy/#nginx","title":"Nginx","text":"
    server {\n  listen 80 default_server;\n  server_name romm.mysite.com;\n  client_max_body_size 0;\n\n  location / {\n    include /config/nginx/proxy.conf;\n    include /config/nginx/resolver.conf;\n    set $upstream_app romm;\n    set $upstream_port 8080;\n    set $upstream_proto http;\n    proxy_pass $upstream_proto://$upstream_app:$upstream_port;\n  }\n}\n
    "},{"location":"Getting-Started/Reverse-Proxy/#nginx-tls-https","title":"Nginx + TLS (HTTPS)","text":"
    server {\n  listen 80 default_server;\n  server_name _;\n  return 301 https://$host$request_uri;\n}\n\nserver {\n    listen 443 ssl http2;\n    listen [::]:443 ssl http2;\n\n    server_name romm.mysite.com;\n    include /config/nginx/ssl.conf;\n    client_max_body_size 0;\n\n    location / {\n      include /config/nginx/proxy.conf;\n      include /config/nginx/resolver.conf;\n      set $upstream_app romm;\n      set $upstream_port 8080;\n      set $upstream_proto http;\n      proxy_pass $upstream_proto://$upstream_app:$upstream_port;\n\n      # Hide version\n      server_tokens off;\n\n      # Security headers\n      add_header X-Frame-Options \"SAMEORIGIN\" always;\n      add_header X-Content-Type-Options \"nosniff\" always;\n      add_header X-XSS-Protection \"1; mode=block\" always;\n      add_header Strict-Transport-Security \"max-age=31536000; includeSubDomains\" always;\n      add_header Referrer-Policy \"no-referrer-when-downgrade\" always;\n    }\n}\n
    "},{"location":"Getting-Started/Reverse-Proxy/#nginx-proxy-manager","title":"Nginx Proxy Manager","text":"

    Items marked with \u2757 are important to set, as RomM may not work correctly otherwise!

    "},{"location":"Getting-Started/Reverse-Proxy/#details","title":"\u26a1 Details","text":""},{"location":"Getting-Started/Reverse-Proxy/#ssl","title":"\ud83d\udee1\ufe0f SSL","text":"

    Strongly recommended for security; enable this if you plan to use HTTPS.

    "},{"location":"Getting-Started/Reverse-Proxy/#advanced","title":"\u2699\ufe0f Advanced","text":"

    Custom Nginx Configuration \u2757

    proxy_max_temp_file_size 0;\n
    Details SSL Advanced"},{"location":"Getting-Started/Reverse-Proxy/#traefik","title":"Traefik","text":""},{"location":"Getting-Started/Reverse-Proxy/#using-a-configuration-document","title":"Using a configuration document","text":"
    http:\n    romsdomainse:\n        entryPoints:\n            - \"https\"\n        rule: \"Host(`roms.domain.se`)\"\n        middlewares:\n            - default-headers\n            - https-redirectscheme\n        tls:\n            certResolver: http\n        service: romsdomainse\n\nservices:\n    romsdomainse:\n        loadBalancer:\n            servers:\n                - url: \"http://192.168.1.100:8080\"\n            passHostHeader: true\n
    "},{"location":"Getting-Started/Reverse-Proxy/#using-labels-in-docker-compose","title":"Using labels in docker compose","text":"
    labels:\n    - \"traefik.enable=true\"\n    - \"traefik.http.services.romm.loadbalancer.server.port=8080\"\n    - \"traefik.http.routers.romm.rule=Host(`romm.YOUR_DOMAIN.com`)\"\n    - \"traefik.http.routers.romm.entrypoints=websecure\"\n    - \"traefik.http.routers.romm.tls=true\"\n    - \"traefik.http.routers.romm.tls.certresolver=https\"\n
    "},{"location":"Integrations/Playnite-plugin/","title":"Playnite plugin","text":"

    Playnite is an open source video game library manager with one simple goal: To provide a unified interface for all of your games.

    This plugin allows you to import your RomM library into Playnite. It queries the RomM API to create Playnite library entires for each of your games. Installing a game in Playnite will download it from RomM and store it on your system, allowing you to launch it in your emulator of choice.

    "},{"location":"Integrations/Playnite-plugin/#installation","title":"Installation","text":""},{"location":"Integrations/Playnite-plugin/#setup","title":"Setup","text":""},{"location":"Integrations/Playnite-plugin/#emulators","title":"Emulators","text":"

    The plugin requires that you have at least 1 emulator installed on your system and configured in Playnite. You can use a built-in emulator or a custom one. If no emulators are installed and configured, you won't be able to complete setup! To set up an emulator, go to Menu -> Library -> Configure Emulators... -> Add emulator....

    "},{"location":"Integrations/Playnite-plugin/#settings","title":"Settings","text":"

    The plugin needs to be configured before it can be used. To do this, go to Menu -> Library -> Configure Integrations... -> RomM.

    "},{"location":"Integrations/Playnite-plugin/#authentication","title":"Authentication","text":"

    You'll need to enter the host URL of your RomM instance, as well as a username and password. Passwords are stored in plaintext in Playnite, so it's recommended to use a separate account with the \"VIEWER\" role. The host URL has the include the protocol (http/https) and should not include a trailing slash, e.g. https://romm.example.com.

    "},{"location":"Integrations/Playnite-plugin/#emulator-path-mappings","title":"Emulator path mappings","text":"Field Description Example Required Emulator A built-in (or custom) emulator Dolphin \u2713 Emulator Profile A built-in (or custom) emulator profile Nintendo GameCube \u2713 Platform The platform or console Nintendo GameCube \u2713 Destination Path The path where downloaded ROMs will be stored C:\\roms\\gc \u2713 Auto-extract Whether compressed files should be extracted automatically Enabled Whether the mapping is enabled"},{"location":"Integrations/Playnite-plugin/#importing-your-library","title":"Importing your library","text":"

    Once you've set up the plugin, you can import your library by going to Menu -> Library -> Import RomM library. All games matching the emulator path mappings will be imported into Playnite.

    Installing a game will download it from RomM and store it in the destination path. You can then launch the game from Playnite, and it will be launched using the configured emulator.

    By default, compressed files will be extracted automatically into a folder matching the game's name. You can modify this behavior in the settings page.

    "},{"location":"Integrations/Tinfoil-integration/","title":"Tinfoil Integration","text":"

    Tinfoil is a homebrew application for the Nintendo Switch, primarily used for installing and managing software, including games and updates, that are not obtained through official channels.

    This will help you configure Tinfoil for your Switch to work with your RomM library.

    "},{"location":"Integrations/Tinfoil-integration/#setup","title":"Setup","text":""},{"location":"Integrations/Tinfoil-integration/#prepare","title":"Prepare","text":"

    Please note down the following in order to make this as smooth as possible, as well as some pre-reqs:

    "},{"location":"Integrations/Tinfoil-integration/#configure","title":"Configure","text":"

    Now it's time to configure your switch - Please follow the steps, this will assume you have Tinfoil installed and know how to use the basic functions of it.

    1. Open Tinfoil and go to File Browser
    2. Scroll over to the selection and press - in order to access the new menu.
    3. Enter these Options
    4. Press X to save
    5. Now close out of Tinfoil and go back in, so it can scan the TitleIDs - if everything is correct you will have this custom motd: \" RomM Switch Library\"

    Now you will be able to see the files in \"New Games\" tab of Tinfoil OR you can access it within the \"File Browser\" section that you setup earlier.

    "},{"location":"Integrations/Tinfoil-integration/#additional","title":"Additional","text":"

    It didn't pull anything through to \"New Games\" and has not parsed any information about the titles?!

    That would be because the filename it has tried to pull had no TitleID (Improvement to RomM coming soon )

    Make sure the filename has the TitleID within the title like this:

    Once this is done, the next time Tinfoil is opened it is always parsed and re-scanned.

    "},{"location":"Integrations/muOS-app/","title":"muOS app","text":"

    muOS is a Custom Firmware (CFW) primarily for handheld devices. Configurable, themeable, friendly, easy-to-use.

    The muOS app connects to your RomM instance and allows you to fetch games wirelessly from your Anbernic device.

    "},{"location":"Integrations/muOS-app/#setup","title":"Setup","text":""},{"location":"Integrations/muOS-app/#muos","title":"muOS","text":"

    We leverage the muOS Archive Manager to install/update the app.

    1. Head to the latest release and download the RomM.muOS.x.x.x.muxapp file.
    2. Move the muxapp file to /mnt/mmc/ARCHIVE on your device.
    3. Launch the manager from Applications > Archive Manager and select RomM.muOS.x.x.x.muxapp.
    4. Once installed, make a copy of /mnt/mmc/MUOS/application/RomM/env.template, rename it to /mnt/mmc/MUOS/application/RomM/.env, edit it (any method is fine, we recommend SSH) and set HOST, USERNAME and PASSWORD.
    5. Launch the app from Applications > RomM and start browsing your collection.
    "},{"location":"Integrations/muOS-app/#emulationstation","title":"EmulationStation","text":"

    We use PortMaster to install the app on devices running EmulationStation.

    1. Download the RomM App.sh file and RomM/ folder to the roms/ports on your device.
    2. Make the RomM App.sh file executable by running chmod +x RomM App.sh.
    3. Launch EmulationStation and navigate to the Ports section.

    Note

    Your device must connect to your RomM instance or home server over Wi-Fi. The easiest method is to keep them on the same network and set HOST to the server's IP and the port where RomM is running. Advanced users or those using reverse proxies can configure their network and DNS settings as needed, using a URL with a domain like https://romm.domain.com.

    "},{"location":"Maintenance/Migrating-to-new-machine/","title":"Migrating RomM","text":""},{"location":"Maintenance/Migrating-to-new-machine/#migrating-romm-to-a-new-system","title":"Migrating RomM to a new system","text":"

    Migrating RomM to a new system is possible, but all of the docker volumes must be copied for RomM to run correctly.

    Following the the setup in the Quick Start Guide these volumes are created be default

    RomM should be stopped before following this guide.

    volumes:\n    mysql_data:\n    romm_resources:\n    romm_redis_data:\n\nservices:\n    romm:\n        volumes:\n            - romm_resources\n            - romm_redis_data\n    romm-db:\n        volumes:\n            - mysql_data\n

    These volumes will need to manually moved to the new system. This is a straightforward process that includes determining their location and then copying them.

    "},{"location":"Maintenance/Migrating-to-new-machine/#determining-the-docker-root-directory-and-copying-the-volumes","title":"Determining the docker root directory and copying the volumes","text":"
    1. First determine the docker root directory
    docker info | grep 'Docker Root Dir'\n

    The expected output on a standard linux system:

    Docker Root Dir: /var/lib/docker\n
    1. Double check that the volumes have been created by docker and are owned by the docker engine
    docker volume ls\n

    Following the default quick start guide the following volumes will have been made

    DRIVER    VOLUME NAME\nlocal     romm_mysql_data\nlocal     romm_romm_redis_data\nlocal     romm_romm_resources\n
    1. Inspect each volume to get the exact location of the volume data
    docker volume inspect romm_mysql_data | grep Mountpoint\n
    \"Mountpoint\": \"/var/lib/docker/volumes/romm_mysql_data/_data\",\n
    1. Copy those volumes into a new location so that they can be safely migrated to a new system each volume needs to be in its own folder
    cp -r /var/lib/docker/volumes/romm_mysql_data/_data/ /your/new/path/romm_mysql_data\n\ncp -r /var/lib/docker/volumes/romm_romm_redis_data/_data /your/new/path/romm_romm_redis_data\n\ncp -r /var/lib/docker/volumes/romm_romm_resources/_data /your/new/path/romm_romm_resources\n
    1. Update the docker-compose.yml volume paths with the newly copied data to determine RomM still loads correctly.
    services:\n    romm:\n        volumes:\n            - /your/new/path/romm_romm_resources # romm_resources\n            - /your/new/path/romm_romm_redis_data # romm_redis_data\n    romm-db:\n        volumes:\n            - /your/new/path/romm_mysql_data # mysql_data\n

    If RomM starts up correctly, then it is safe to copy all of your RomM folders to a new system.

    "},{"location":"Maintenance/Scheduled-Tasks/","title":"Scheduled Tasks","text":""},{"location":"Maintenance/Scheduled-Tasks/#scheduled-tasks","title":"Scheduled tasks","text":"

    Scheduled tasks can be enabled and configured with the following environment variables:

    Variable Description Value ENABLE_SCHEDULED_RESCAN Enable scheduled re-scanning of library true SCHEDULED_RESCAN_CRON Cron expression for scheduled re-scanning \"0 3 * * *\" ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB Enable scheduled updating of Switch TitleDB index true SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON Cron expression for scheduled updating of Switch TitleDB \"0 4 * * *\" ENABLE_SCHEDULED_UPDATE_LAUNCHBOX_METADATA Enable scheduled updating of LaunchBox metadata true SCHEDULED_UPDATE_LAUNCHBOX_METADATA_CRON. Cron expression for scheduled updating of LaunchBox metadata \"0 5 * * *\""},{"location":"Maintenance/Scheduled-Tasks/#scheduled-re-scan","title":"Scheduled re-scan","text":"

    Users can opt to enable scheduled re-scans, and set the interval using Cron notation. Not that the scan will not completely re-scan every file, only catching those which have been added/updated.

    "},{"location":"Maintenance/Scheduled-Tasks/#switch-titledb-update","title":"Switch titleDB update","text":"

    Support was added for Nintendo Switch ROMs with filenames using the titleid/programid format (e.g. 0100000000010000.xci). If a file under the switch folder matches the regex, the scanner will use the index to attempt to match it to a game. If a match is found, the IGDB handler will use the matched name as the search term.

    The associated task updates the /fixtures/switch_titledb.json file at a regular interval to support new game releases.

    "},{"location":"Maintenance/Scheduled-Tasks/#launchbox-metadata-update","title":"LaunchBox metadata update","text":"

    RomM can also update the LaunchBox metadata database at a regular interval. This is onyl useful if you've enabled the LaunchBox metadata provider. The database is updated by downloading the latest version from the LaunchBox Games Database and replacing the existing one.

    "},{"location":"Maintenance/Scheduled-Tasks/#file-system-watcher","title":"File system watcher","text":"

    RomM can also monitor the filesystem for events (files created/moved/deleted) and schedules a re-scan of the platform (or entire library is a new platform was added).

    The watcher can be enabled and configured with the following environment variables:

    Variable Description Value ENABLE_RESCAN_ON_FILESYSTEM_CHANGE Enable re-scanning of library when filesystem changes true RESCAN_ON_FILESYSTEM_CHANGE_DELAY Delay in minutes before re-scanning library when filesystem changes 5

    The watcher will monitor the /library/roms folder for changes to the filesystem, such as files being added, moved or deleted. It will ignore certain events (like modifying the file content or metadata), and will skip default OS files (like .DS_Store on mac).

    When a change is detected, a scan will be scheduled for sometime in the future (default 5 minutes). If other events are triggered between now and the time at which the scan starts, more platforms will be added to the scan list (or the scan may switch to a full scan). This is done to reduce the number of tasks scheduled when many big changes happen to the library (mass upload, new mount, etc.)

    "},{"location":"Maintenance/Upgrading-to-3.0/","title":"Upgrading to 3.0","text":"

    Version 3.0 of RomM introduces a number of breaking changes aimed at improving performance and usability, which will require some users to make specific changes before upgrading to ensure compatibility and to take full advantage of the new features.

    All of the following changes are reflected in the example docker-compose.yml file, which has been simplified greatly. Please read this entire file carefully, as failing to do so may cause RomM to become inaccessible or unresponsive.

    "},{"location":"Maintenance/Upgrading-to-3.0/#dropped-support-for-sqlite","title":"Dropped support for SQLite","text":"

    We're removed support for SQLite as we've faced a number of engineering issues with it in the past, and MariaDB has proven more stable and robust. If you currently use SQLite, we'll automatically migrate your data from SQLite to MariaDB, but you'll first need to make the following changes before upgrading to the latest image.

    In your environment variables, change ROMM_DB_DRIVER to mariadb (or remove it completely as it's no longer needed). You'll then want to add the following environment variables:

    - DB_HOST=mariadb\n- DB_PORT=3306\n- DB_NAME=romm # Should match MYSQL_DATABASE in mariadb\n- DB_USER=romm-user # Should match MYSQL_USER in mariadb\n- DB_PASSWD= # Should match MYSQL_PASSWORD in mariadb\n

    To setup a new MariaDB container, have a look at the example docker-compose.yml file.

    "},{"location":"Maintenance/Upgrading-to-3.0/#authentication-as-standard","title":"Authentication as standard","text":"

    To support new features like EmulatorJS and saves/states management, we've decided to require authentication for all users. Anyone currently running RomM with authentication disabled will need to remove the ROMM_AUTH_ENABLED environment variable and add the following ones:

    - ROMM_AUTH_SECRET_KEY= # Generate a key with `openssl rand -hex 32`\n

    We understand that this requirement for authentication might conflict with the way some users currently share their collection with others (unrestricted access for all). However, given the exciting new features we've built, and the ones we're looking to build in the near future, we feel this is the right decision for the project.

    "},{"location":"Maintenance/Upgrading-to-3.0/#redis-is-now-built-in","title":"Redis is now built-in","text":"

    As Redis is required for authentication to work, we've integrated it directly into the docker image. If you're currently running the experimental Redis container, you can remove it, along with these environment variables:

    - ENABLE_EXPERIMENTAL_REDIS\n- REDIS_HOST\n- REDIS_PORT\n
    "},{"location":"Maintenance/Upgrading-to-3.0/#configuration-folder","title":"Configuration folder","text":"

    Mounting the config.yml file is now done by mounting a config folder.. Place your existing config.yml file inside a folder and bind it to /romm/config:

    - /path/to/config:/romm/config\n

    Updated config.example.yml

    "},{"location":"Maintenance/Upgrading-to-3.0/#support-for-saves-states-and-screenshots","title":"Support for saves, states and screenshots","text":"

    This version introduces preliminary support for uploading/downloading saves, states and screenshots (read more about it in the 3.0 release notes). We've added a new volume mapping for these types of files called assets, which you'll want to bind to a local folder (or volume) so they'll persist. In your volumes section, add the following mapping, where /path/to/assets/ is some folder where you'll want to store these assets (and make sure that folder exists):

    - /path/to/assets:/romm/assets\n

    We recommend creating a folder next to your library/the one mapped to /romm/library in order to keep all your RomM files in the same place.

    "},{"location":"Miscellaneous/Brand-Guidelines/","title":"Branding Guidelines","text":"

    We\u2019ve put together some guidelines for those anyone who wants to use our name and logo. In this context, \"RomM\", \"The RomM Project\", \"the project\", \"we\", \"us\", and \"our\" refer to the RomM project.

    "},{"location":"Miscellaneous/Brand-Guidelines/#the-logo","title":"The Logo","text":"The logo should always be used in its standard colors: Color Hex Code #371f69 #553e98 #ede5f8 #bea4e1 #e6c7a7 #e1a38d"},{"location":"Miscellaneous/Brand-Guidelines/#do-these-things","title":"Do these things","text":"

    If you're working on a project that integrates with RomM and would like to use/remix the logo, please reach out to us first. We'd love to hear about what you're working on!

    "},{"location":"Miscellaneous/Brand-Guidelines/#please-dont-do-these-things","title":"Please don't do these things","text":""},{"location":"Miscellaneous/FAQs/","title":"FAQs","text":""},{"location":"Miscellaneous/FAQs/#when-will-the-next-version-of-romm-be-available","title":"When will the next version of RomM be available?","text":"

    When it's ready.

    "},{"location":"Miscellaneous/FAQs/#when-will-the-version-after-that-one-release","title":"When will the version after that one release?","text":"

    After the upcoming version is released.

    "},{"location":"Miscellaneous/FAQs/#when-will-x-feature-be-available","title":"When will X feature be available?","text":"

    Sometime between now and the heat death of the universe.

    "},{"location":"Miscellaneous/FAQs/#when-will-version-xxx-of-romm-or-any-of-the-romm-clientsappsplugins-be-released","title":"When will version x.x.x of RomM (or any of the RomM clients/apps/plugins) be released?","text":"

    Same as above question.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/","title":"With Authelia","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#oidc-setup-with-authelia","title":"OIDC Setup With Authelia","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#a-quick-rundown-of-the-technologies","title":"A quick rundown of the technologies","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#what-is-authelia","title":"What is Authelia?","text":"

    Authelia is an open-source authentication and authorization server providing two-factor authentication and single sign-on (SSO) for your applications via a web portal. It acts as a companion for reverse proxies by allowing, denying, or redirecting requests. Authelia can be deployed alongside your other services to centralize identity management.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#what-is-oauth2","title":"What is OAuth2?","text":"

    OAuth2 (Open Authorization 2.0) is an industry-standard protocol for authorization. It allows applications (clients) to gain limited access to user accounts on an HTTP service without sharing the user\u2019s credentials. Instead, it uses access tokens to facilitate secure interactions. OAuth2 is commonly used in scenarios where users need to authenticate via a third-party service.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#what-is-openid-connect-oidc","title":"What is OpenID Connect (OIDC)?","text":"

    OIDC (OpenID Connect) is an identity layer built on top of OAuth2. While OAuth2 primarily handles authorization, OIDC adds authentication, enabling applications to verify a user\u2019s identity and obtain profile information. This makes OIDC suitable for SSO solutions, where user identity is central to access management.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#setting-up-a-provider-and-application-in-authelia","title":"Setting up a Provider and Application in Authelia","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#step-1-install-and-configure-authelia","title":"Step 1: Install and Configure Authelia","text":"

    Before setting up a provider and app, ensure that Authelia is installed and running by following the getting started and OIDC provider guides.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#step-2-add-a-client","title":"Step 2: Add a client","text":"

    First, in Authelia's configuration.yml, at identity_providers \u2192 oidc \u2192 claims_policies you'll need to add a Claims Policy if you do not already have one with the specified claims:

    # identity_providers:\n#   oidc:\nclaims_policies:\n    with_email: # You can name this however you want\n        id_token:\n            [\n                \"email\",\n                \"email_verified\",\n                \"alt_emails\",\n                \"preferred_username\",\n                \"name\",\n            ]\n

    To read more about claims_policies and why you need it for RomM, see this section in the Authelia docs.

    Then, in the same configuration.yml, under identity_providers \u2192 oidc \u2192 clients, add a new entry:

    Refer to the official docs for more details.

    This entry should look like this:

    #identity_providers:\n#  oidc:\n#    clients:\n- client_id: \"<randomly_generated>\" # read above for how generate\n  client_name: \"RomM\" # will be displayed in Authelia to users\n  client_secret: \"$pbkdf2-sha512$randomly_generated\" # read above for how generate\n  public: false\n  authorization_policy: \"two_factor\" # or one_factor, depending on your needs\n  grant_types:\n      - authorization_code\n  redirect_uris:\n      - \"http://romm.host.local/api/oauth/openid\"\n  claims_policy: \"with_email\"\n  scopes:\n      - \"openid\"\n      - \"email\"\n      - \"profile\"\n  userinfo_signed_response_alg: \"none\"\n  token_endpoint_auth_method: \"client_secret_basic\"\n
    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#step-3-configure-romm-environment-variables","title":"Step 3: Configure RomM Environment Variables","text":"

    To enable OIDC authentication in RomM, you need to set the following environment variables:

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#step-4-set-your-email-in-romm","title":"Step 4: Set your Email in RomM","text":"

    In RomM, open your user profile and set your email address. This email has to match your user email in Authelia.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#step-5-test-the-integration","title":"Step 5: Test the Integration","text":"

    After configuring the environment variables, restart (or stop and remove) your RomM instance and navigate to the login page. You should see an option to log in using OIDC. Click on the OIDC button, and you'll be redirected to Authelia for authentication. Once authenticated, you'll be redirected back to RomM.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/","title":"With Authentik","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#oidc-setup-with-authentik","title":"OIDC Setup With Authentik","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#a-quick-rundown-of-the-technologies","title":"A quick rundown of the technologies","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#what-is-authentik","title":"What is Authentik?","text":"

    Authentik is an open-source identity provider (IdP) designed to manage authentication, authorization, and user management across applications. It supports modern authentication protocols and provides tools to simplify integration, including single sign-on (SSO), multi-factor authentication (MFA), and auditing capabilities. Authentik can be deployed alongside your other services to centralize identity management.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#what-is-oauth2","title":"What is OAuth2?","text":"

    OAuth2 (Open Authorization 2.0) is an industry-standard protocol for authorization. It allows applications (clients) to gain limited access to user accounts on an HTTP service without sharing the user\u2019s credentials. Instead, it uses access tokens to facilitate secure interactions. OAuth2 is commonly used in scenarios where users need to authenticate via a third-party service.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#what-is-openid-connect-oidc","title":"What is OpenID Connect (OIDC)?","text":"

    OIDC (OpenID Connect) is an identity layer built on top of OAuth2. While OAuth2 primarily handles authorization, OIDC adds authentication, enabling applications to verify a user\u2019s identity and obtain profile information. This makes OIDC suitable for SSO solutions, where user identity is central to access management.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#setting-up-a-provider-and-application-in-authentik","title":"Setting up a Provider and Application in Authentik","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#step-1-install-and-configure-authentik","title":"Step 1: Install and Configure Authentik","text":"

    Before setting up a provider and app, ensure that Authentik is installed and running by following the official installation guide..

    1. Access Authentik via its web interface.
    2. Log in as an administrator.
    3. Navigate to the \u201cAdmin Interface\u201d to configure the necessary components.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#step-2-create-a-provider","title":"Step 2: Create a Provider","text":"

    A provider in Authentik acts as the bridge between RomM and Authentik.

    1. Navigate to Providers:
    2. Create a New Provider:
    3. Select \"OAuth2/OpenID Provider\"
    4. Configure Provider Settings:
    5. Copy the Client ID and Secret:
    6. Click Create.
    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#step-3-register-an-application","title":"Step 3: Register an Application","text":"

    An app in Authentik represents the external service (in our case RomM) that will use the provider for authentication.

    1. Navigate to Applications:
    2. Create a New Application:
    3. Click Create.
    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#step-4-configure-romm-environment-variables","title":"Step 4: Configure RomM Environment Variables","text":"

    To enable OIDC authentication in RomM, you need to set the following environment variables:

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#step-5-set-your-email-in-romm","title":"Step 5: Set your Email in RomM","text":"

    In RomM, open your user profile and set your email address. This email has to match your user email in Authentik.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#step-6-test-the-integration","title":"Step 6: Test the Integration","text":"

    After configuring the environment variables, restart (or stop and remove) your RomM instance and navigate to the login page. You should see an option to log in using OIDC. Click on the OIDC button, and you'll be redirected to Authentik for authentication. Once authenticated, you'll be redirected back to RomM.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/","title":"With PocketID","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#oidc-setup-with-pocket-id","title":"OIDC Setup With Pocket ID","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#a-quick-rundown-of-the-technologies","title":"A quick rundown of the technologies","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#what-is-pocket-id","title":"What is Pocket ID?","text":"

    Pocket ID is a simple OIDC provider that allows users to authenticate with their passkeys to your services.

    The goal of Pocket ID is to be a simple and easy-to-use. There are other self-hosted OIDC providers like Keycloak or ORY Hydra but they are often too complex for simple use cases.

    Additionally, what makes Pocket ID special is that it only supports passkey authentication, which means you don\u2019t need a password.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#what-is-oauth2","title":"What is OAuth2?","text":"

    OAuth2 (Open Authorization 2.0) is an industry-standard protocol for authorization. It allows applications (clients) to gain limited access to user accounts on an HTTP service without sharing the user\u2019s credentials. Instead, it uses access tokens to facilitate secure interactions. OAuth2 is commonly used in scenarios where users need to authenticate via a third-party service.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#what-is-openid-connect-oidc","title":"What is OpenID Connect (OIDC)?","text":"

    OIDC (OpenID Connect) is an identity layer built on top of OAuth2. While OAuth2 primarily handles authorization, OIDC adds authentication, enabling applications to verify a user\u2019s identity and obtain profile information. This makes OIDC suitable for SSO solutions, where user identity is central to access management.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#setting-up-a-client-in-pocket-id","title":"Setting up a client in Pocket ID","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#step-1-install-and-configure-pocket-id","title":"Step 1: Install and Configure Pocket ID","text":"

    Before setting up the OIDC client, ensure that Pocket ID is installed and running by following the setup guide.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#step-2-add-a-client","title":"Step 2: Add a client","text":"

    Once you have logged in and configured a PassKey you now need to create an OIDC client, this will let Pocket ID know about the application that needs to be configured, and will give you the relevant keys to add to the RomM compose file.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#step-3-configure-romm-environment-variables","title":"Step 3: Configure RomM Environment Variables","text":"

    To enable OIDC authentication in RomM, you need to set the following environment variables:

    "},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#step-4-set-your-email-in-romm","title":"Step 4: Set your Email in RomM","text":"

    In RomM, open your user profile and set your email address. This email has to match your user email in Pocket ID.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#step-5-test-the-integration","title":"Step 5: Test the Integration","text":"

    After configuring the environment variables, restart (or stop and remove) your RomM instance and navigate to the login page. You should see an option to log in using OIDC. Click on the OIDC button, and you'll be redirected to Pocket ID for authentication. Once authenticated, you'll be redirected back to RomM.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/","title":"With Zitadel","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#oidc-setup-with-zitadel","title":"OIDC Setup With Zitadel","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#a-quick-rundown-of-the-technologies","title":"A quick rundown of the technologies","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#what-is-zitadel","title":"What is Zitadel","text":"

    Zitadel is an enterprise-grade, open-source identity and access management (IAM) platform that supports OAuth2, OpenID Connect, SAML, and passwordless authentication. It's used to manage users, roles, and secure login for web and cloud applications.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#what-is-oauth2","title":"What is OAuth2?","text":"

    OAuth2 (Open Authorization 2.0) is an industry-standard protocol for authorization. It allows applications (clients) to gain limited access to user accounts on an HTTP service without sharing the user\u2019s credentials. Instead, it uses access tokens to facilitate secure interactions. OAuth2 is commonly used in scenarios where users need to authenticate via a third-party service.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#what-is-openid-connect-oidc","title":"What is OpenID Connect (OIDC)?","text":"

    OIDC (OpenID Connect) is an identity layer built on top of OAuth2. While OAuth2 primarily handles authorization, OIDC adds authentication, enabling applications to verify a user\u2019s identity and obtain profile information. This makes OIDC suitable for SSO solutions, where user identity is central to access management.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#setting-up-a-client-in-zitadel","title":"Setting up a client in Zitadel","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#step-1-install-and-configure-zitadel","title":"Step 1: Install and Configure Zitadel","text":"

    Before setting up the OIDC client, ensure that Zitadel is installed and running by following the setup guide.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#step-2-create-a-project","title":"Step 2: Create a Project","text":"

    Once you have logged in and changed the default password for your Zitadel organization, create a new Project (i.e Romm). This will be the basic settings for roles and authorization.

    In the \"General\" tab, there are options to allow the following:

    Unnecessary: Romm (at this time) does not allow granting permissions based on role, everyone gets viewer and will have to be changed manually using an admin account if desired.

    Recommended: If you allow registration to your platform, then anyone who registers can instantly access Romm (although only as a viewer, which may not be a problem for some)

    Optional: It could be used if you plan on separating users by organizations for other applications, but creating separate organizations is not typically useful for general self-hosting purposes

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#step-25-optional-if-you-enabled-check-authorization-on-authentication-grant-users-access-to-the-project","title":"Step 2.5 (Optional: If you enabled \"Check authorization on Authentication\"): Grant user(s) access to the Project","text":"

    Click on the Authorization tab and click New.

    Enter the user(s) and click Continue

    It should say \"No role has been created yet.\", but this is fine, you can just click Save and it should bring you back to the Authorization page with your user(s) listed with no roles

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#step-3-create-the-application","title":"Step 3: Create the application","text":"

    On the General tab, click the New button under Applications.

    (Check \"I'm a pro. Skip this wizard.\" to enter the information quicker)

    Click Create.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#step-3-configure-romm-environment-variables","title":"Step 3: Configure RomM Environment Variables","text":"

    To enable OIDC authentication in RomM, you need to set the following environment variables:

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#step-4-enable-claims-from-id-token-this-resolves-the-email-is-missing-from-token-error","title":"Step 4: Enable claims from ID Token (this resolves the \"Email is missing from token\" error)","text":"

    Click close to finish creating the application and then go to the Token Settings tab.

    Check \"User Info inside ID Token\" and click Save

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#step-5-set-your-email-in-romm","title":"Step 5: Set your Email in RomM","text":"

    For your existing RomM admin account, open your user profile on Zitadel and set your email address. This email has to match your user email in Zitadel.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#step-6-test-the-integration","title":"Step 6: Test the Integration","text":"

    After configuring the environment variables, restart (or stop and remove) your RomM instance and navigate to the login page. You should see the option \"LOGIN WITH ZITADEL\". Click on it and you'll be redirected to Zitadel for authentication. Once authenticated, you'll be redirected back to RomM.

    "},{"location":"Platforms-and-Players/Custom-Platforms/","title":"Custom Platforms","text":"

    While RomM supports every platform listed in the Supported Platforms page, the list is not exhaustive, and you may have ROMs in your library for other platforms. To load those files into RomM, place them in a folder for each platform, and give it a name that's all lowercase, with - to separate words, and with no white spaces. For example, pocket-challenge-v2 would map to Pocket Challenge V2, and display the default platform icon in the app.

    Furthermore, only a portion of the supported platforms have custom icons built-in. If your library has platforms that aren't listed in the platforms icons list, RomM will display a default fallback icon.

    If you'd like to load your own custom icons for missing platforms, you can mount /var/www/html/assets/platforms to some local folder and place all of your custom .ico platform icons in there. You'll also want to download the ones provided in this project and place them in the same folder. If you'd like to use your own icons for platforms already supported by RomM, just replace the file with another using the exact same name.

    The name of the .ico file should match the slug of the platform on IGDB. For example, the URL for the AmstradCPC is https://www.igdb.com/platforms/acpc, so the filename should be acpc.ico.

    "},{"location":"Platforms-and-Players/EmulatorJS-Player/","title":"EmulatorJS","text":"

    EmulatorJS is a web-based emulator for various system; that is, it allows you to run old games in your web browser. It's based on RetroArch compiled with Emscripten, which is a toolchain for compiling C and C++ code to WebAssembly.

    Warning

    Note

    Some platforms may require multiple BIOS/firmware files to be loaded at the same time. To do this, create a ZIP archive containing all the firmware files for the emulator you've selected and upload it to the firmware section of the platform. This ZIP file will be recognized by EmulatorJS as the firmware bundle for the platform. Refer to the EmulatorJS documentation for the required list of files for each platform.

    "},{"location":"Platforms-and-Players/EmulatorJS-Player/#saves-and-states","title":"Saves and states","text":"

    Our integration with EmulatorJS automates the process of loading and save files and save states. Before starting the game, select a save and/or state file to load (if one is available). Anytime you manually save the game (or create a save state) by clicking the save or \"save and quit\" buttons, the save and state files stored with RomM will be updated, so there's no need to manually download or upload them.

    "},{"location":"Platforms-and-Players/EmulatorJS-Player/#netplay","title":"Netplay","text":"

    Netplay lets you play with friends remotely, in realtime with the build-in web player. As it emulates playing on the same console with two controllers while streaming the video to players 2+, it's best for 2-player, co-op, turn based and party games.

    Start by enabling netplay in your config.yml:

    emulatorjs:\n    netplay:\n        enabled: true\n

    If you require ICE servers for NAT traversal, we recommend a free-tier Metered account. Create new \"TURN Credentials\" and replace <username> and <password> with the entries under \"Show ICE Server Array\":

    emulatorjs:\n    netplay:\n        ice_servers:\n            - urls: \"stun:stun.relay.metered.ca:80\"\n            - urls: \"stun:stun.relay.metered.ca:80\"\n            - urls: \"turn:global.relay.metered.ca:80\"\n              username: \"<username>\"\n              credential: \"<password>\"\n            - urls: \"turn:global.relay.metered.ca:80?transport=tcp\"\n              username: \"<username>\"\n              credential: \"<password>\"\n            - urls: \"turn:global.relay.metered.ca:443\"\n              username: \"<username>\"\n              credential: \"<password>\"\n            - urls: \"turns:global.relay.metered.ca:443?transport=tcp\"\n              username: \"<username>\"\n              credential: \"<password>\"\n

    Alternatively, use the free STUN servers from Google and TURN servers via the OpenRelayProject:

    emulatorjs:\n    netplay:\n        ice_servers:\n            - urls: \"stun:stun.l.google.com:19302\"\n            - urls: \"stun:stun1.l.google.com:19302\"\n            - urls: \"stun:stun2.l.google.com:19302\"\n            - urls: \"turn:openrelay.metered.ca:80\"\n              username: \"openrelayproject\"\n              credential: \"openrelayproject\"\n            - urls: \"turn:openrelay.metered.ca:443\"\n              username: \"openrelayproject\"\n              credential: \"openrelayproject\"\n

    To host a game, start it, then hit the \ud83c\udf10 icon in botton bar. Set your name, create a room (password optional), and other players should be able to see and join your room. All players need access to your RomM server to join a room and play together.

    "},{"location":"Platforms-and-Players/EmulatorJS-Player/#supported-systems","title":"Supported systems","text":"

    Note that only the following systems are currently supported:

    "},{"location":"Platforms-and-Players/MS-DOS/","title":"MS-DOS","text":"

    DOS is now supported in versions of RomM 4.0 and above thanks to the EmulatorJS player - Simply create a DOS platform to enable the integration

    Info

    I highly suggest you upload the games as .zip as the core can take advantage of unzipping and auto mounting options which are explained more below.

    Info

    Loading and saving states ARE supported so it's possible you only need to do the below steps once to load the game.

    "},{"location":"Platforms-and-Players/MS-DOS/#running-games","title":"Running Games","text":"

    Once you have the play button in the platform available for you there is some additional work you need to do in order to get the games playable and running. You first need to identify what DOS game you are trying to run, there would be three categories

    The official method to run the games from the EmulatorJS dev is the following (Only works for Homebrew and Demos):

    "},{"location":"Platforms-and-Players/MS-DOS/#advanced-running-games","title":"Advanced Running Games","text":"

    Warning

    This is not for the faint of heart and will require a lot of trial and error.

    As the system is using DOSBOX pure it has a neat trick where it will run .CONF files it finds and automatically mount locations and run .exe files automatically, at the minute this is highly experimental and might be more effort then it is worth, but if you want the files running perfectly then I would suggest you look into this method, but it is extremely trail and error.

    When you run a game in DOSBOX Pure, before it runs and mounts anything it will look for a .conf file and follow those instructions, this way we can actually auto mount locations, mount the required CDs and play the game without typing anything, you just click play, the auto mount does everything in the background and you are presented with the game.

    This is an example using the doom shareware file which has all the files in the folder.

    DOOM.conf Example
    # This is the configurationfile for DOSBox 0.74. (Please use the latest version of DOSBox)\n# Lines starting with a # are commentlines and are ignored by DOSBox.\n# They are used to (briefly) document the effect of each option.\n\n[sdl]\n#       fullscreen: Start dosbox directly in fullscreen. (Press ALT-Enter to go back)\n#       fulldouble: Use double buffering in fullscreen. It can reduce screen flickering, but it can also result in a slow DOSBox.\n#   fullresolution: What resolution to use for fullscreen: original or fixed size (e.g. 1024x768).\n#                     Using your monitor's native resolution with aspect=true might give the best results.\n#                     If you end up with small window on a large screen, try an output different from surface.\n# windowresolution: Scale the window to this size IF the output device supports hardware scaling.\n#                     (output=surface does not!)\n#           output: What video system to use for output.\n#                   Possible values: surface, overlay, opengl, openglnb, ddraw.\n#         autolock: Mouse will automatically lock, if you click on the screen. (Press CTRL-F10 to unlock)\n#      sensitivity: Mouse sensitivity.\n#      waitonerror: Wait before closing the console if dosbox has an error.\n#         priority: Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized.\n#                     pause is only valid for the second entry.\n#                   Possible values: lowest, lower, normal, higher, highest, pause.\n#       mapperfile: File used to load/save the key/event mappings from. Resetmapper only works with the defaul value.\n#     usescancodes: Avoid usage of symkeys, might not work on all operating systems.\n\nfullscreen=TRUE\nfulldouble=false\nfullresolution=Fixed\nwindowresolution=1280x800\noutput=direct3d\nautolock=true\nsensitivity=100\nwaitonerror=true\npriority=higher,normal\nmapperfile=mapper-0.74.map\nusescancodes=true\n\n[dosbox]\n# language: Select another language file.\n#  machine: The type of machine tries to emulate.\n#           Possible values: hercules, cga, tandy, pcjr, ega, vgaonly, svga_s3, svga_et3000, svga_et4000, svga_paradise, vesa_nolfb, vesa_oldvbe.\n# captures: Directory where things like wave, midi, screenshot get captured.\n#  memsize: Amount of memory DOSBox has in megabytes.\n#             This value is best left at its default to avoid problems with some games,\n#             though few games might require a higher value.\n#             There is generally no speed advantage when raising this value.\n\nlanguage=\nmachine=svga_s3\ncaptures=.\\Captures\\\nmemsize=16\n\n[render]\n# frameskip: How many frames DOSBox skips before drawing one.\n#    aspect: Do aspect correction, if your output method doesn't support scaling this can slow things down!.\n#    scaler: Scaler used to enlarge/enhance low resolution modes.\n#              If 'forced' is appended, then the scaler will be used even if the result might not be desired.\n#            Possible values: none, normal2x, normal3x, advmame2x, advmame3x, advinterp2x, advinterp3x, hq2x, hq3x, 2xsai, super2xsai, supereagle, tv2x, tv3x, rgb2x, rgb3x, scan2x, scan3x.\n\nframeskip=0\naspect=false\nscaler=normal3x\n\n[cpu]\n#      core: CPU Core used in emulation. auto will switch to dynamic if available and appropriate.\n#            Possible values: auto, dynamic, normal, simple.\n#   cputype: CPU Type used in emulation. auto is the fastest choice.\n#            Possible values: auto, 386, 386_slow, 486_slow, pentium_slow, 386_prefetch.\n#    cycles: Amount of instructions DOSBox tries to emulate each millisecond.\n#            Setting this value too high results in sound dropouts and lags.\n#            Cycles can be set in 3 ways:\n#              'auto'          tries to guess what a game needs.\n#                              It usually works, but can fail for certain games.\n#              'fixed #number' will set a fixed amount of cycles. This is what you usually need if 'auto' fails.\n#                              (Example: fixed 4000).\n#              'max'           will allocate as much cycles as your computer is able to handle.\n#\n#            Possible values: auto, fixed, max.\n#   cycleup: Amount of cycles to decrease/increase with keycombo.(CTRL-F11/CTRL-F12)\n# cycledown: Setting it lower than 100 will be a percentage.\n\ncore=auto\ncputype=auto\ncycles=max\ncycleup=10\ncycledown=20\n\n[mixer]\n#   nosound: Enable silent mode, sound is still emulated though.\n#      rate: Mixer sample rate, setting any device's rate higher than this will probably lower their sound quality.\n#            Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.\n# blocksize: Mixer block size, larger blocks might help sound stuttering but sound will also be more lagged.\n#            Possible values: 1024, 2048, 4096, 8192, 512, 256.\n# prebuffer: How many milliseconds of data to keep on top of the blocksize.\n\nnosound=false\nrate=22050\nblocksize=2048\nprebuffer=10\n\n[midi]\n#     mpu401: Type of MPU-401 to emulate.\n#             Possible values: intelligent, uart, none.\n# mididevice: Device that will receive the MIDI data from MPU-401.\n#             Possible values: default, win32, alsa, oss, coreaudio, coremidi, none.\n# midiconfig: Special configuration options for the device driver. This is usually the id of the device you want to use.\n#               See the README/Manual for more details.\n\nmpu401=intelligent\nmididevice=default\nmidiconfig=\n\n[sblaster]\n#  sbtype: Type of Soundblaster to emulate. gb is Gameblaster.\n#          Possible values: sb1, sb2, sbpro1, sbpro2, sb16, gb, none.\n#  sbbase: The IO address of the soundblaster.\n#          Possible values: 220, 240, 260, 280, 2a0, 2c0, 2e0, 300.\n#     irq: The IRQ number of the soundblaster.\n#          Possible values: 7, 5, 3, 9, 10, 11, 12.\n#     dma: The DMA number of the soundblaster.\n#          Possible values: 1, 5, 0, 3, 6, 7.\n#    hdma: The High DMA number of the soundblaster.\n#          Possible values: 1, 5, 0, 3, 6, 7.\n# sbmixer: Allow the soundblaster mixer to modify the DOSBox mixer.\n# oplmode: Type of OPL emulation. On 'auto' the mode is determined by sblaster type. All OPL modes are Adlib-compatible, except for 'cms'.\n#          Possible values: auto, cms, opl2, dualopl2, opl3, none.\n#  oplemu: Provider for the OPL emulation. compat might provide better quality (see oplrate as well).\n#          Possible values: default, compat, fast.\n# oplrate: Sample rate of OPL music emulation. Use 49716 for highest quality (set the mixer rate accordingly).\n#          Possible values: 44100, 49716, 48000, 32000, 22050, 16000, 11025, 8000.\n\nsbtype=sb16\nsbbase=220\nirq=7\ndma=1\nhdma=5\nsbmixer=true\noplmode=auto\noplemu=default\noplrate=44100\n\n[gus]\n#      gus: Enable the Gravis Ultrasound emulation.\n#  gusrate: Sample rate of Ultrasound emulation.\n#           Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.\n#  gusbase: The IO base address of the Gravis Ultrasound.\n#           Possible values: 240, 220, 260, 280, 2a0, 2c0, 2e0, 300.\n#   gusirq: The IRQ number of the Gravis Ultrasound.\n#           Possible values: 5, 3, 7, 9, 10, 11, 12.\n#   gusdma: The DMA channel of the Gravis Ultrasound.\n#           Possible values: 3, 0, 1, 5, 6, 7.\n# ultradir: Path to Ultrasound directory. In this directory\n#           there should be a MIDI directory that contains\n#           the patch files for GUS playback. Patch sets used\n#           with Timidity should work fine.\n\ngus=false\ngusrate=44100\ngusbase=240\ngusirq=5\ngusdma=3\nultradir=C:\\ULTRASND\n\n[speaker]\n# pcspeaker: Enable PC-Speaker emulation.\n#    pcrate: Sample rate of the PC-Speaker sound generation.\n#            Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.\n#     tandy: Enable Tandy Sound System emulation. For 'auto', emulation is present only if machine is set to 'tandy'.\n#            Possible values: auto, on, off.\n# tandyrate: Sample rate of the Tandy 3-Voice generation.\n#            Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.\n#    disney: Enable Disney Sound Source emulation. (Covox Voice Master and Speech Thing compatible).\n\npcspeaker=true\npcrate=44100\ntandy=auto\ntandyrate=44100\ndisney=true\n\n[joystick]\n# joysticktype: Type of joystick to emulate: auto (default), none,\n#               2axis (supports two joysticks),\n#               4axis (supports one joystick, first joystick used),\n#               4axis_2 (supports one joystick, second joystick used),\n#               fcs (Thrustmaster), ch (CH Flightstick).\n#               none disables joystick emulation.\n#               auto chooses emulation depending on real joystick(s).\n#               (Remember to reset dosbox's mapperfile if you saved it earlier)\n#               Possible values: auto, 2axis, 4axis, 4axis_2, fcs, ch, none.\n#        timed: enable timed intervals for axis. Experiment with this option, if your joystick drifts (away).\n#     autofire: continuously fires as long as you keep the button pressed.\n#       swap34: swap the 3rd and the 4th axis. can be useful for certain joysticks.\n#   buttonwrap: enable button wrapping at the number of emulated buttons.\n\njoysticktype=fcs\ntimed=true\nautofire=false\nswap34=false\nbuttonwrap=false\n\n[serial]\n# serial1: set type of device connected to com port.\n#          Can be disabled, dummy, modem, nullmodem, directserial.\n#          Additional parameters must be in the same line in the form of\n#          parameter:value. Parameter for all types is irq (optional).\n#          for directserial: realport (required), rxdelay (optional).\n#                           (realport:COM1 realport:ttyS0).\n#          for modem: listenport (optional).\n#          for nullmodem: server, rxdelay, txdelay, telnet, usedtr,\n#                         transparent, port, inhsocket (all optional).\n#          Example: serial1=modem listenport:5000\n#          Possible values: dummy, disabled, modem, nullmodem, directserial.\n# serial2: see serial1\n#          Possible values: dummy, disabled, modem, nullmodem, directserial.\n# serial3: see serial1\n#          Possible values: dummy, disabled, modem, nullmodem, directserial.\n# serial4: see serial1\n#          Possible values: dummy, disabled, modem, nullmodem, directserial.\n\nserial1=dummy\nserial2=dummy\nserial3=disabled\nserial4=disabled\n\n[dos]\n#            xms: Enable XMS support.\n#            ems: Enable EMS support.\n#            umb: Enable UMB support.\n# keyboardlayout: Language code of the keyboard layout (or none).\n\nxms=true\nems=true\numb=true\nkeyboardlayout=auto\n\n[ipx]\n# ipx: Enable ipx over UDP/IP emulation.\n\nipx=false\n\n[autoexec]\n# Lines in this section will be run at startup.\n# You can put your MOUNT lines here.\n\n@echo off\nMount C \"..\"\nC:\ncls\nDOOM.exe\n:exit\nexit\n
    "},{"location":"Platforms-and-Players/MS-DOS/#advanced-running-retail-games","title":"Advanced Running Retail Games","text":"

    Info

    At the minute DOS games redesigned by GOG are NOT supported, this is due to how they mount and use the locations. I am looking into how I can figure this out but I have had a 100% failure rate from the GOG DOS Games.

    Retail games usually require to run alongside a disk even if the game has been \"installed\" locally. I will use Dungeon Keeper Gold as an example for a retail game with a disc and the configuration needed.

    KEEPER.conf Example
    # This is the configurationfile for DOSBox 0.74. (Please use the latest version of DOSBox)\n# Lines starting with a # are commentlines and are ignored by DOSBox.\n# They are used to (briefly) document the effect of each option.\n\n[sdl]\n#       fullscreen: Start dosbox directly in fullscreen. (Press ALT-Enter to go back)\n#       fulldouble: Use double buffering in fullscreen. It can reduce screen flickering, but it can also result in a slow DOSBox.\n#   fullresolution: What resolution to use for fullscreen: original or fixed size (e.g. 1024x768).\n#                     Using your monitor's native resolution with aspect=true might give the best results.\n#                     If you end up with small window on a large screen, try an output different from surface.\n# windowresolution: Scale the window to this size IF the output device supports hardware scaling.\n#                     (output=surface does not!)\n#           output: What video system to use for output.\n#                   Possible values: surface, overlay, opengl, openglnb, ddraw.\n#         autolock: Mouse will automatically lock, if you click on the screen. (Press CTRL-F10 to unlock)\n#      sensitivity: Mouse sensitivity.\n#      waitonerror: Wait before closing the console if dosbox has an error.\n#         priority: Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized.\n#                     pause is only valid for the second entry.\n#                   Possible values: lowest, lower, normal, higher, highest, pause.\n#       mapperfile: File used to load/save the key/event mappings from. Resetmapper only works with the defaul value.\n#     usescancodes: Avoid usage of symkeys, might not work on all operating systems.\n\nfullscreen=TRUE\nfulldouble=false\nfullresolution=Fixed\nwindowresolution=1280x800\noutput=direct3d\nautolock=true\nsensitivity=100\nwaitonerror=true\npriority=higher,normal\nmapperfile=mapper-0.74.map\nusescancodes=true\n\n[dosbox]\n# language: Select another language file.\n#  machine: The type of machine tries to emulate.\n#           Possible values: hercules, cga, tandy, pcjr, ega, vgaonly, svga_s3, svga_et3000, svga_et4000, svga_paradise, vesa_nolfb, vesa_oldvbe.\n# captures: Directory where things like wave, midi, screenshot get captured.\n#  memsize: Amount of memory DOSBox has in megabytes.\n#             This value is best left at its default to avoid problems with some games,\n#             though few games might require a higher value.\n#             There is generally no speed advantage when raising this value.\n\nlanguage=\nmachine=svga_s3\ncaptures=.\\Captures\\\nmemsize=16\n\n[render]\n# frameskip: How many frames DOSBox skips before drawing one.\n#    aspect: Do aspect correction, if your output method doesn't support scaling this can slow things down!.\n#    scaler: Scaler used to enlarge/enhance low resolution modes.\n#              If 'forced' is appended, then the scaler will be used even if the result might not be desired.\n#            Possible values: none, normal2x, normal3x, advmame2x, advmame3x, advinterp2x, advinterp3x, hq2x, hq3x, 2xsai, super2xsai, supereagle, tv2x, tv3x, rgb2x, rgb3x, scan2x, scan3x.\n\nframeskip=0\naspect=false\nscaler=normal3x\n\n[cpu]\n#      core: CPU Core used in emulation. auto will switch to dynamic if available and appropriate.\n#            Possible values: auto, dynamic, normal, simple.\n#   cputype: CPU Type used in emulation. auto is the fastest choice.\n#            Possible values: auto, 386, 386_slow, 486_slow, pentium_slow, 386_prefetch.\n#    cycles: Amount of instructions DOSBox tries to emulate each millisecond.\n#            Setting this value too high results in sound dropouts and lags.\n#            Cycles can be set in 3 ways:\n#              'auto'          tries to guess what a game needs.\n#                              It usually works, but can fail for certain games.\n#              'fixed #number' will set a fixed amount of cycles. This is what you usually need if 'auto' fails.\n#                              (Example: fixed 4000).\n#              'max'           will allocate as much cycles as your computer is able to handle.\n#\n#            Possible values: auto, fixed, max.\n#   cycleup: Amount of cycles to decrease/increase with keycombo.(CTRL-F11/CTRL-F12)\n# cycledown: Setting it lower than 100 will be a percentage.\n\ncore=auto\ncputype=auto\ncycles=max\ncycleup=10\ncycledown=20\n\n[mixer]\n#   nosound: Enable silent mode, sound is still emulated though.\n#      rate: Mixer sample rate, setting any device's rate higher than this will probably lower their sound quality.\n#            Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.\n# blocksize: Mixer block size, larger blocks might help sound stuttering but sound will also be more lagged.\n#            Possible values: 1024, 2048, 4096, 8192, 512, 256.\n# prebuffer: How many milliseconds of data to keep on top of the blocksize.\n\nnosound=false\nrate=22050\nblocksize=2048\nprebuffer=10\n\n[midi]\n#     mpu401: Type of MPU-401 to emulate.\n#             Possible values: intelligent, uart, none.\n# mididevice: Device that will receive the MIDI data from MPU-401.\n#             Possible values: default, win32, alsa, oss, coreaudio, coremidi, none.\n# midiconfig: Special configuration options for the device driver. This is usually the id of the device you want to use.\n#               See the README/Manual for more details.\n\nmpu401=intelligent\nmididevice=default\nmidiconfig=\n\n[sblaster]\n#  sbtype: Type of Soundblaster to emulate. gb is Gameblaster.\n#          Possible values: sb1, sb2, sbpro1, sbpro2, sb16, gb, none.\n#  sbbase: The IO address of the soundblaster.\n#          Possible values: 220, 240, 260, 280, 2a0, 2c0, 2e0, 300.\n#     irq: The IRQ number of the soundblaster.\n#          Possible values: 7, 5, 3, 9, 10, 11, 12.\n#     dma: The DMA number of the soundblaster.\n#          Possible values: 1, 5, 0, 3, 6, 7.\n#    hdma: The High DMA number of the soundblaster.\n#          Possible values: 1, 5, 0, 3, 6, 7.\n# sbmixer: Allow the soundblaster mixer to modify the DOSBox mixer.\n# oplmode: Type of OPL emulation. On 'auto' the mode is determined by sblaster type. All OPL modes are Adlib-compatible, except for 'cms'.\n#          Possible values: auto, cms, opl2, dualopl2, opl3, none.\n#  oplemu: Provider for the OPL emulation. compat might provide better quality (see oplrate as well).\n#          Possible values: default, compat, fast.\n# oplrate: Sample rate of OPL music emulation. Use 49716 for highest quality (set the mixer rate accordingly).\n#          Possible values: 44100, 49716, 48000, 32000, 22050, 16000, 11025, 8000.\n\nsbtype=sb16\nsbbase=220\nirq=7\ndma=1\nhdma=5\nsbmixer=true\noplmode=auto\noplemu=default\noplrate=44100\n\n[gus]\n#      gus: Enable the Gravis Ultrasound emulation.\n#  gusrate: Sample rate of Ultrasound emulation.\n#           Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.\n#  gusbase: The IO base address of the Gravis Ultrasound.\n#           Possible values: 240, 220, 260, 280, 2a0, 2c0, 2e0, 300.\n#   gusirq: The IRQ number of the Gravis Ultrasound.\n#           Possible values: 5, 3, 7, 9, 10, 11, 12.\n#   gusdma: The DMA channel of the Gravis Ultrasound.\n#           Possible values: 3, 0, 1, 5, 6, 7.\n# ultradir: Path to Ultrasound directory. In this directory\n#           there should be a MIDI directory that contains\n#           the patch files for GUS playback. Patch sets used\n#           with Timidity should work fine.\n\ngus=false\ngusrate=44100\ngusbase=240\ngusirq=5\ngusdma=3\nultradir=C:\\ULTRASND\n\n[speaker]\n# pcspeaker: Enable PC-Speaker emulation.\n#    pcrate: Sample rate of the PC-Speaker sound generation.\n#            Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.\n#     tandy: Enable Tandy Sound System emulation. For 'auto', emulation is present only if machine is set to 'tandy'.\n#            Possible values: auto, on, off.\n# tandyrate: Sample rate of the Tandy 3-Voice generation.\n#            Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.\n#    disney: Enable Disney Sound Source emulation. (Covox Voice Master and Speech Thing compatible).\n\npcspeaker=true\npcrate=44100\ntandy=auto\ntandyrate=44100\ndisney=true\n\n[joystick]\n# joysticktype: Type of joystick to emulate: auto (default), none,\n#               2axis (supports two joysticks),\n#               4axis (supports one joystick, first joystick used),\n#               4axis_2 (supports one joystick, second joystick used),\n#               fcs (Thrustmaster), ch (CH Flightstick).\n#               none disables joystick emulation.\n#               auto chooses emulation depending on real joystick(s).\n#               (Remember to reset dosbox's mapperfile if you saved it earlier)\n#               Possible values: auto, 2axis, 4axis, 4axis_2, fcs, ch, none.\n#        timed: enable timed intervals for axis. Experiment with this option, if your joystick drifts (away).\n#     autofire: continuously fires as long as you keep the button pressed.\n#       swap34: swap the 3rd and the 4th axis. can be useful for certain joysticks.\n#   buttonwrap: enable button wrapping at the number of emulated buttons.\n\njoysticktype=fcs\ntimed=true\nautofire=false\nswap34=false\nbuttonwrap=false\n\n[serial]\n# serial1: set type of device connected to com port.\n#          Can be disabled, dummy, modem, nullmodem, directserial.\n#          Additional parameters must be in the same line in the form of\n#          parameter:value. Parameter for all types is irq (optional).\n#          for directserial: realport (required), rxdelay (optional).\n#                           (realport:COM1 realport:ttyS0).\n#          for modem: listenport (optional).\n#          for nullmodem: server, rxdelay, txdelay, telnet, usedtr,\n#                         transparent, port, inhsocket (all optional).\n#          Example: serial1=modem listenport:5000\n#          Possible values: dummy, disabled, modem, nullmodem, directserial.\n# serial2: see serial1\n#          Possible values: dummy, disabled, modem, nullmodem, directserial.\n# serial3: see serial1\n#          Possible values: dummy, disabled, modem, nullmodem, directserial.\n# serial4: see serial1\n#          Possible values: dummy, disabled, modem, nullmodem, directserial.\n\nserial1=dummy\nserial2=dummy\nserial3=disabled\nserial4=disabled\n\n[dos]\n#            xms: Enable XMS support.\n#            ems: Enable EMS support.\n#            umb: Enable UMB support.\n# keyboardlayout: Language code of the keyboard layout (or none).\n\nxms=true\nems=true\numb=true\nkeyboardlayout=auto\n\n[ipx]\n# ipx: Enable ipx over UDP/IP emulation.\n\nipx=false\n\n[autoexec]\n# Lines in this section will be run at startup.\n# You can put your MOUNT lines here.\n\n@echo off\nMount C \"..\"\nC:\ncd CD\nimgmount d DUNGEO~8.CUE -t iso -fs iso\ncd ..\ncls\nKEEPER.exe\n:exit\nexit\n
    "},{"location":"Platforms-and-Players/MS-DOS/#advanced-game-troubleshooting","title":"Advanced Game Troubleshooting","text":"

    If the games are not working and you go back to a blank dos looking screen, this will require some manual troubleshooting but I have found success with the following methods:

    Another way of troubleshooting is to use Retroarch and the core \"dosbox-pure\" because if it runs in here, it will run in RomM. Simply give it your ZIP and it will act the same as if you was doing it through RomM, once the .conf file is perfected add it back to the ZIP.

    "},{"location":"Platforms-and-Players/RuffleRS-Player/","title":"RuffleRS","text":"

    Ruffle is a web-based player for flash games. With flash now discontinued, this is the best way to play your flash collection in the browser.

    Important

    Ruffle will only play games stored in platform folders called flash or browser.

    "},{"location":"Platforms-and-Players/Supported-Platforms/","title":"Supported Platforms","text":"

    Below is a list of all supported platforms/systems/consoles and their respective folder names. Supported platforms means RomM can fetch metadata from sources for those platforms.

    Info

    For platforms that can be playable in the browser, please check EmulatorJS supported platforms and RuffleRS player.

    Danger

    The folder name is case-sensitive and must be used exactly as it appears in the list below.

    Filter providers

    0 of 0 platforms shown Platform Name Folder Name Metadata Providers 1292 Advanced Programmable Video System 1292-advanced-programmable-video-system 3DO Interactive Multiplayer 3do 8-Bit Productions Commander X16 commander-x16 Aamber Pegasus pegasus ABC 80 abc-80 Acorn Archimedes acorn-archimedes Acorn Electron acorn-electron Advanced Pico Beena advanced-pico-beena Adventure Vision adventure-vision AirConsole airconsole Alice 32/90 alice-3290 Altair 680 altair-680 Altair 8800 altair-8800 Amazon Alexa amazon-alexa Amazon Fire TV amazon-fire-tv Amiga amiga Amiga CD amiga-cd Amiga CD32 amiga-cd32 Amstrad CPC acpc Amstrad GX4000 amstrad-gx4000 Amstrad PCW amstrad-pcw Analogue electronics analogueelectronics Android android Antstream antstream APF MP1000/Imagination Machine apf Apogee BK-01 bk-01 Apple I apple Apple II appleii Apple IIGS apple-iigs Apple III appleiii Apple Lisa apple-lisa Apple Pippin apple-pippin Arcade arcade Arcadia 2001 arcadia-2001 Arduboy arduboy Astral 2000 astral-2000 Atari 2600 atari2600 Atari 5200 atari5200 Atari 7800 atari7800 Atari 8-bit atari8bit Atari 800 atari800 Atari Jaguar jaguar Atari Jaguar CD atari-jaguar-cd Atari Lynx lynx Atari ST/STE atari-st Atari VCS atari-vcs Atari XEGS atari-xegs Atom atom AY-3-8500 ay-3-8500 AY-3-8603 ay-3-8603 AY-3-8605 ay-3-8605 AY-3-8606 ay-3-8606 AY-3-8607 ay-3-8607 AY-3-8610 ay-3-8610 AY-3-8710 ay-3-8710 AY-3-8760 ay-3-8760 Bada bada Bally Astrocade astrocade BBC Microcomputer System bbcmicro Benesse Pocket Challenge V2 pocket-challenge-v2 Benesse Pocket Challenge W pocket-challenge-w BeOS beos BGR Computers Excalibur 64 excalibur-64 Bit Corporation BIT 90 bit-90 Black Point black-point BlackBerry OS blackberry Blacknut blacknut Blu-ray Player blu-ray-player BREW brew Browser (Flash/HTML5) browser Bubble bubble Call-A-Computer time-shared mainframe computer system call-a-computer Cambridge Computer Z88 z88 Camputers Lynx camputers-lynx Casio CFX-9850 casio-cfx-9850 Casio FP-1000 & FP-1100 casio-fp-1000 Casio Loopy casio-loopy Casio PB-1000 casio-pb-1000 Casio Programmable Calculator casio-programmable-calculator Casio PV-1000 casio-pv-1000 Casio PV-2000 casio-pv-2000 CDC Cyber 70 cdccyber70 Champion 2711 champion-2711 ClickStart clickstart Coleco Adam colecoadam ColecoVision colecovision Colour Genie colour-genie Commodore 128 c128 Commodore 16 c16 Commodore C64/128/MAX c64 Commodore CDTV commodore-cdtv Commodore PET cpet Commodore Plus/4 c-plus-4 Commodore VIC-20 vic-20 Compal 80 compal-80 Compucolor I compucolor-i Compucolor II compucolor-ii Compucorp Programmable Calculator compucorp-programmable-calculator COSMAC fred-cosmac CP/M cpm CreatiVision creativision Cybervision cybervision Danger OS danger-os Daydream daydream DEC GT40 gt40 Dedicated console dedicated-console Dedicated handheld dedicated-handheld Didj didj Digiblast digiblast DoJa doja Donner Model 30 donner30 DOS dos Dragon 32/64 dragon-32-slash-64 Dreamcast dc DVD Player dvd-player e-Reader / Card-e Reader e-reader-slash-card-e-reader ECD Micromind ecd-micromind EDSAC edsac Elektor TV Games Computer elektor Elektronika BK bk Enterprise enterprise Epoch Cassette Vision epoch-cassette-vision Epoch Game Pocket Computer epoch-game-pocket-computer Epoch Super Cassette Vision epoch-super-cassette-vision Evercade evercade Exelvision exelvision ExEn exen Exidy Sorcerer exidy-sorcerer Fairchild Channel F fairchild-channel-f Family Computer famicom Family Computer Disk System fds Feature phone mobile-custom Ferranti Nimrod Computer nimrod FM Towns fm-towns FM-7 fm-7 Freebox freebox G-cluster g-cluster Galaksija galaksija Gamate gamate Game & Watch g-and-w Game Boy gb Game Boy Advance gba Game Boy Color gbc Game Master hartung Game Wave game-wave Game.com game-dot-com GameStick gamestick Gear VR gear-vr GIMINI gimini Gizmondo gizmondo Gloud gloud Glulx glulx GNEX gnex Google Stadia stadia GP2X gp2x GP2X Wiz gp2x-wiz GP32 gp32 GVM gvm Handheld Electronic LCD handheld-electronic-lcd HD DVD Player hd-dvd-player Heath/Zenith H8/H89 heathzenith Heathkit H11 heathkit-h11 Hector HRX hrx Hitachi S1 hitachi-s1 HP 2100 hp2100 HP 3000 hp3000 HP 9800 hp-9800 HP Programmable Calculator hp-programmable-calculator Hugo hugo Hyper Neo Geo 64 hyper-neo-geo-64 HyperScan hyperscan IBM 5100 ibm-5100 IBM PCjr pc-jr Ideal-Computer ideal-computer iiRcade iircade Imlac PDS-1 imlac-pds1 Intel 8008 intel-8008 Intel 8080 intel-8080 Intel 8086 / 8088 intel-8086 Intellivision intellivision Intellivision Amico intellivision-amico Interact Model One interact-model-one Interton VC 4000 interton-vc-4000 Interton Video 2000 interton-video-2000 iOS ios iPad ipad iPod Classic ipod-classic J2ME j2me Jolt jolt Jupiter Ace jupiter-ace KaiOS kaios KIM-1 kim-1 Kindle Classic kindle Laser 200 laser200 LaserActive laseractive LeapFrog Explorer leapfrog-explorer Leapster leapster Leapster Explorer/LeadPad Explorer leapster-explorer-slash-leadpad-explorer LeapTV leaptv Legacy Computer legacy-computer Legacy Mobile Device mobile Linux linux Luna luna Mac mac Maemo maemo Magnavox Odyssey odyssey Mainframe mainframe Matsushita/Panasonic JR matsushitapanasonic-jr Mattel Aquarius aquarius MeeGo meego Mega Duck/Cougar Boy mega-duck-slash-cougar-boy Memotech MTX memotech-mtx Memotech MTX512 mtx512 Meritum meritum Meta Quest 2 meta-quest-2 Meta Quest 3 meta-quest-3 Microbee microbee Microcomputer microcomputer Microsoft MSX2+ msx2plus Microtan 65 microtan-65 Microvision microvision Mophun mophun MOS Technology 6502 mos-technology-6502 Motorola 6800 motorola-6800 Motorola 68k motorola-68k MRE mre MSX msx MSX Turbo R msx-turbo MSX2 msx2 MUGEN mugen N-Gage ngage N-Gage (service) ngage2 Namco System 22 system-32 Nascom nascom NEC PC-6000 Series nec-pc-6000-series Neo Geo AES neogeoaes Neo Geo CD neo-geo-cd Neo Geo MVS neogeomvs Neo Geo Pocket neo-geo-pocket Neo Geo Pocket Color neo-geo-pocket-color Neo Geo X neo-geo-x New Nintendo 3DS new-nintendo-3ds NewBrain newbrain Newton newton Nintendo 3DS 3ds Nintendo 64 n64 Nintendo 64DD 64dd Nintendo DS nds Nintendo DSi nintendo-dsi Nintendo Entertainment System nes Nintendo GameCube ngc Nintendo Switch switch Nintendo Switch 2 switch-2 North Star northstar Noval 760 noval-760 Nuon nuon Oculus Go oculus-go Oculus Quest oculus-quest Oculus Rift oculus-rift Oculus VR oculus-vr Odyssey 2 odyssey-2 Ohio Scientific ohio-scientific OnLive Game System onlive-game-system OOParts ooparts OpenBOR openbor Orao orao Oric oric Oric Atmos atmos OS/2 os2 Othello Multivision multivision Ouya ouya Palm OS palm-os Palmtex palmtex Panasonic Jungle panasonic-jungle Panasonic M2 panasonic-m2 Pandora pandora PC Booter pc-booter PC Engine SuperGrafx supergrafx PC-50X Family pc-50x-family PC-6001 pc-6001 PC-8000 pc-8000 PC-8800 Series pc-8800-series PC-9800 Series pc-9800-series PC-FX pc-fx PDP-1 pdp1 PDP-10 pdp10 PDP-11 pdp11 PDP-7 pdp-7 PDP-8 pdp-8 Pebble pebble Philips CD-i philips-cd-i Philips VG 5000 philips-vg-5000 Photo CD photocd PICO pico Pinball pinball Pippin pippin PLATO plato Playdate playdate Playdia playdia PlayStation psx PlayStation 2 ps2 PlayStation 3 ps3 PlayStation 4 ps4 PlayStation 5 ps5 PlayStation Now playstation-now PlayStation Portable psp PlayStation Vita psvita PlayStation VR psvr PlayStation VR2 psvr2 Plex Arcade plex-arcade Plug & Play plug-and-play PocketStation pocketstation Pokitto pokitto Pok\u00e9mon mini pokemon-mini Poly-88 poly-88 Polymega polymega R-Zone r-zone RCA Studio II rca-studio-ii Research Machines 380Z research-machines-380z Roku roku SAM Coup\u00e9 sam-coupe Satellaview satellaview SC/MP scmp ScummVM scummvm SD-200/270/290 sd-200270290 SDS Sigma 7 sdssigma7 Sega 32X sega32 Sega Advanced Pico Beena beena Sega CD segacd Sega CD 32X segacd32 Sega Dreamcast VMU vmu Sega Game Gear gamegear Sega Hikaru hikaru Sega Master System/Mark III sms Sega Mega Drive/Genesis genesis Sega Model 1 model1 Sega Model 2 model2 Sega Model 3 model3 Sega Pico sega-pico Sega Saturn saturn Sega SC-3000 sc3000 Sega ST-V stv Sega System 16 system16 Sega System 32 system32 SG-1000 sg1000 Sharp MZ-2200 sharp-mz-2200 Sharp MZ-80B/2000/2500 sharp-mz-80b20002500 Sharp MZ-80K/700/800/1500 sharp-mz-80k7008001500 Sharp X1 x1 Sharp X68000 sharp-x68000 Sharp Zaurus sharp-zaurus Signetics 2650 signetics-2650 Sinclair QL sinclair-ql Sinclair ZX81 zx81 SK-VM sk-vm SMC-777 smc-777 Socrates socrates Sol-20 sol-20 Sony PSP Minis psp-minis Sord M5 sord-m5 Spectravideo spectravideo SRI-500/1000 sri-5001000 SteamVR steam-vr Sufami Turbo sufami-turbo Super A'Can super-acan Super Famicom sfam Super NES CD-ROM System super-nes-cd-rom-system Super Nintendo Entertainment System snes Super Vision 8000 super-vision-8000 Sure Shot HD sure-shot-hd SwanCrystal swancrystal SWTPC 6800 swtpc-6800 Symbian symbian TADS tads Taito Type X type-x Taito X-55 taito-x-55 Tandy Vis tandy-vis Tapwave Zodiac zod Tatung Einstein tatung-einstein Tektronix 4050 tektronix-4050 Tele-Spiel ES-2201 tele-spiel Telstar Arcade telstar-arcade Terebikko / See 'n Say Video Phone terebikko-slash-see-n-say-video-phone Terminal terminal Texas Instruments TI-82 ti-82 Texas Instruments TI-83 ti-83 Texas Instruments TI-99 ti-99 Thomson MO5 thomson-mo5 Thomson TO thomson-to TI Programmable Calculator ti-programmable-calculator TI-99/4A ti-994a Tiki 100 tiki-100 TIM tim Timex Sinclair 2068 timex-sinclair-2068 Tizen tizen Tomahawk F1 tomahawk-f1 Tomy Tutor tomy-tutor Tomy Tutor / Pyuta / Grandstand Tutor tomy-tutor-slash-pyuta-slash-grandstand-tutor Triton triton TRS-80 trs-80 TRS-80 Color Computer trs-80-color-computer TRS-80 MC-10 trs-80-mc-10 TRS-80 Model 100 trs-80-model-100 TurboGrafx-16/PC Engine tg16 Turbografx-16/PC Engine CD turbografx-cd tvOS tvos Uzebox uzebox V.Flash vflash V.Smile vsmile VC 4000 vc-4000 Vector-06C 06c Vectrex vectrex Versatile versatile VideoBrain videobrain Videopac+ G7400 videopac-g7400 Virtual Boy virtualboy Virtual Console vc VIS vis visionOS visionos Visual Memory Unit / Visual Memory System visual-memory-unit-slash-visual-memory-system Wang 2200 wang2200 WASM-4 wasm-4 Watara/QuickShot Supervision supervision watchOS watchos webOS webos Wii wii Wii U wiiu Windows win Windows 3.x win3x Windows Apps windows-apps Windows Mixed Reality windows-mixed-reality Windows Mobile windows-mobile Windows Phone winphone WIPI wipi WonderSwan wonderswan WonderSwan Color wonderswan-color WoW Action Max action-max XaviXPORT xavixport Xbox xbox Xbox 360 xbox360 Xbox Cloud Gaming xboxcloudgaming Xbox One xboxone Xbox Series X/S series-x-s Xerox Alto xerox-alto Z-machine z-machine Zeebo zeebo Zilog Z80 z80 Zilog Z8000 zilog-z8000 ZiNc zinc Zodiac zodiac Zune zune ZX Spectrum zxs ZX Spectrum Next zx-spectrum-next ZX80 zx80"},{"location":"System-Setup/Synology-Setup-Guide/","title":"Synology Setup","text":""},{"location":"System-Setup/Synology-Setup-Guide/#external-written-guides","title":"External Written Guides","text":"

    While you can follow the below guide, Marius Bogdan Lixandru has written excellent guides which focus on Synology infrastructure and with support for both MariaDB and PostGresSQL:

    We suggest following the above guides if they fit your setup, and the guide below is available for all other use cases.

    "},{"location":"System-Setup/Synology-Setup-Guide/#prerequisites","title":"Prerequisites","text":"

    This guide assumes you're familiar with Docker and have basic knowledge of server management. You'll need:

    "},{"location":"System-Setup/Synology-Setup-Guide/#setup-process","title":"Setup Process","text":""},{"location":"System-Setup/Synology-Setup-Guide/#1-folder-structure-setup","title":"1. Folder Structure Setup","text":""},{"location":"System-Setup/Synology-Setup-Guide/#rom-storage-folders","title":"ROM Storage Folders","text":"

    Create the following directory structure for game assets and configuration:

    mkdir -p /volume1/data/media/games/assets\nmkdir -p /volume1/data/media/games/config\n
    "},{"location":"System-Setup/Synology-Setup-Guide/#rom-library-structure","title":"ROM Library Structure","text":"

    RomM requires a very specific folder structure for rom files:

    mkdir -p /volume1/data/media/games/library/roms\nmkdir -p /volume1/data/media/games/library/bios\n

    Note: For supported platforms and their specific folder names, refer to the official RomM docs.

    "},{"location":"System-Setup/Synology-Setup-Guide/#docker-data-folders","title":"Docker Data Folders","text":"

    Create these folders for project and container data:

    mkdir -p /volume1/docker/romm-project/\nmkdir -p /volume1/docker/romm/resources\nmkdir -p /volume1/docker/romm/redis-data\nmkdir -p /volume1/docker/mariadb-romm\n
    "},{"location":"System-Setup/Synology-Setup-Guide/#2-network-bridge-setup","title":"2. Network Bridge Setup","text":"

    Create a new network bridge named rommbridge following standard Docker networking practices. You can use this guide for reference.

    "},{"location":"System-Setup/Synology-Setup-Guide/#3-key-generation","title":"3. Key Generation","text":""},{"location":"System-Setup/Synology-Setup-Guide/#authentication-key","title":"Authentication Key","text":"

    Generate your authentication key using:

    openssl rand -hex 32\n> 03a054b6ca27e0107c5eed552ea66bacd9f3a2a8a91e7595cd462a593f9ecd09\n

    Save the output - you'll need it for the ROMM_AUTH_SECRET_KEY in your configuration.

    "},{"location":"System-Setup/Synology-Setup-Guide/#api-integration-setup","title":"API Integration Setup","text":"

    Follow the dedicated docs page for API key generation to set up your API keys.

    "},{"location":"System-Setup/Synology-Setup-Guide/#4-mariadb-configuration","title":"4. MariaDB Configuration","text":"

    Important

    "},{"location":"System-Setup/Synology-Setup-Guide/#5-docker-compose-configuration","title":"5. Docker Compose Configuration","text":"

    Create a docker-compose.yml file with the following content:

    Example Docker Compose
    version: \"3\"\n\nvolumes:\n    mysql_data:\n\nservices:\n    romm:\n        image: rommapp/romm:latest\n        container_name: romm\n        restart: unless-stopped\n        environment:\n            - DB_HOST=romm-db\n            - DB_NAME=romm # Should match MARIADB_DATABASE in mariadb\n            - DB_USER=romm-user # Should match MARIADB_USER in mariadb\n            - DB_PASSWD= # Should match MARIADB_PASSWORD in mariadb\n            - ROMM_AUTH_SECRET_KEY= # Generate a key with `openssl rand -hex 32`\n            - SCREENSCRAPER_USER= # These are the recommended metadata providers\n            - SCREENSCRAPER_PASSWORD= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#screenscraper\n            - RETROACHIEVEMENTS_API_KEY= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#retroachievements\n            - STEAMGRIDDB_API_KEY= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#steamgriddb\n            - HASHEOUS_API_ENABLED=true # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#hasheous\n        volumes:\n            - /volume1/docker/romm/resources:/romm/resources\n            - /volume1/docker/romm/redis-data:/redis-data\n            - /volume1/data/media/games/library:/romm/library\n            - /volume1/data/media/games/assets:/romm/assets\n            - /volume1/data/media/games/config:/romm/config\n        ports:\n            - 7676:8080\n        network_mode: rommbridge\n        depends_on:\n            romm-db:\n                condition: service_healthy\n                restart: true\n\n    romm-db:\n        image: mariadb:latest\n        container_name: romm-db\n        restart: unless-stopped\n        environment:\n            - MARIADB_ROOT_PASSWORD= # Use a unique, secure password\n            - MARIADB_DATABASE=romm\n            - MARIADB_USER=romm-user\n            - MARIADB_PASSWORD=\n        ports:\n            - 3309:3306\n        network_mode: rommbridge\n        volumes:\n            - /volume1/docker/mariadb-romm:/var/lib/mysql\n        healthcheck:\n            test: [CMD, healthcheck.sh, --connect, --innodb_initialized]\n            start_period: 30s\n            start_interval: 10s\n            interval: 10s\n            timeout: 5s\n            retries: 5\n
    "},{"location":"System-Setup/Synology-Setup-Guide/#6-initial-launch","title":"6. Initial Launch","text":"
    1. Start the containers using Docker Compose
    2. Be patient! The container can take a few minutes to setup on first launch
    3. Monitor progress through container logs
    4. Access RomM through your browser at http://your-server-ip:7676

    Important

    "},{"location":"System-Setup/Synology-Setup-Guide/#troubleshooting","title":"Troubleshooting","text":""},{"location":"System-Setup/Synology-Setup-Guide/#contributing","title":"Contributing","text":"

    This guide is an abridged version of ChopFoo's original guide. If you have any suggestions or improvements, please submit a pull request to the RomM docs.

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/","title":"TrueNAS Setup","text":""},{"location":"System-Setup/TrueNAS-Setup-Guide/#prerequisites","title":"Prerequisites","text":"

    This guide assumes you're familiar with Docker and have basic knowledge of TrueNAS. You'll need:

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#setup-process","title":"Setup Process","text":""},{"location":"System-Setup/TrueNAS-Setup-Guide/#install-through-the-truenas-app-catalog-recommended","title":"Install through the TrueNAS App Catalog (Recommended)","text":""},{"location":"System-Setup/TrueNAS-Setup-Guide/#step-1-navigate-to-romm-app","title":"Step 1: Navigate to RomM app","text":"

    Navigate to the App Catalog via Apps (Left navigation bar) -> Discover Apps -> RomM -> Install

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#step-2-installation-configuration","title":"Step 2: Installation configuration","text":"

    Step through the installation UI. You will need to supply various credentials per the Quick Start Guide. Most of the default values will work.

    Note: You will likely want to set certain Storage Configurations to a Dataset within TrueNAS, such as your RomM Library and Assets storage. If you do this, ensure you provide ACL access to the UserID specified above (default: 568, apps user).

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#step-3-save-your-configuration","title":"Step 3: Save your configuration","text":"

    Save, and you're done! If the app will not boot, refer to Troubleshooting or head on over to the Discord.

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#install-via-yaml","title":"Install via YAML","text":"

    This installation path should only be used in the event that there is a bug with installing through the App Catalog, or you wish to have more flexibility than is provided by the installation UI.

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#step-1-navigate-to-yaml-install","title":"Step 1: Navigate to YAML install","text":"

    Navigate to the Install via YAML page via Apps (Left navigation bar) -> Discover Apps -> Install via YAML

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#step-2-paste-in-the-following-yml","title":"Step 2: Paste in the following YML","text":"

    Replace any empty values with credentials you've created per the Quick Start Guide.

    Example Docker Compose
    version: \"3\"\n\nvolumes:\n    mysql_data:\n    romm_redis_data:\n\nservices:\n    romm:\n        image: rommapp/romm:latest\n        container_name: romm\n        restart: unless-stopped\n        user: 568:568\n        environment:\n            - DB_HOST=romm-db\n            - DB_NAME=romm # Should match MARIADB_DATABASE in mariadb\n            - DB_USER=romm-user # Should match MARIADB_USER in mariadb\n            - DB_PASSWD= # Should match MARIADB_PASSWORD in mariadb\n            - ROMM_AUTH_SECRET_KEY= # Generate a key with `openssl rand -hex 32`\n            - SCREENSCRAPER_USER= # These are the recommended metadata providers\n            - SCREENSCRAPER_PASSWORD= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#screenscraper\n            - RETROACHIEVEMENTS_API_KEY= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#retroachievements\n            - STEAMGRIDDB_API_KEY= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#steamgriddb\n            - HASHEOUS_API_ENABLED=true # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#hasheous\n        volumes: # Any /mnt paths may optionally be replaced with a docker volume\n            - /mnt/tank/truenas/resources:/romm/resources # Replace /mnt...: file path with your own data structure\n            - romm_redis_data:/romm/redis-data # Docker will manage this volume\n            - /mnt/tank/truenas/roms:/romm/library # Replace /mnt...: file path with your own data structure\n            - /mnt/tank/truenas/assets:/romm/assets # Replace /mnt...: file path with your own data structure\n            - /mnt/tank/truenas/config:/romm/config # Replace /mnt...: file path with your own data structure\n        ports:\n            - 31100:8080\n        depends_on:\n            romm-db:\n                condition: service_healthy\n                restart: true\n        deploy:\n            resources:\n                limits:\n                    cpus: \"2.0\"\n                    memory: 4g\n\n    romm-db:\n        image: mariadb:latest\n        container_name: romm-db\n        restart: unless-stopped\n        environment:\n            - MARIADB_ROOT_PASSWORD= # Use a unique, secure password\n            - MARIADB_DATABASE=romm\n            - MARIADB_USER=romm-user\n            - MARIADB_PASSWORD=\n        volumes:\n            - mysql_data:/var/lib/mysql\n        healthcheck:\n            test: [CMD, healthcheck.sh, --connect, --innodb_initialized]\n            start_period: 30s\n            start_interval: 10s\n            interval: 10s\n            timeout: 5s\n            retries: 5\n
    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#step-3-save-the-configuration","title":"Step 3: Save the configuration","text":"

    Save, and you're done! If the app will not boot, refer to Troubleshooting or head on over to the Discord.

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#troubleshooting","title":"Troubleshooting","text":""},{"location":"System-Setup/TrueNAS-Setup-Guide/#general","title":"General","text":""},{"location":"System-Setup/TrueNAS-Setup-Guide/#specific-issues","title":"Specific Issues","text":""},{"location":"System-Setup/TrueNAS-Setup-Guide/#permissions-issues-inside-the-docker-image","title":"Permissions issues inside the docker image","text":"

    If you are encountering permissions issues with folders internal to the docker image (not your TrueNAS dataset), consider temporarily setting the user to root (user: 0). If you do this, it is recommended you fix local file permissions via shell and return access back to a non-root user.

    In my particular setup, I had to create a user/group in TrueNAS with uid:gid of 1000:1000 and auxiliary group apps due to hard-coded values in the RomM docker image. This resolved outstanding issues I had with my instance of RomM talking to its Redis instance.

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#contributing","title":"Contributing","text":"

    If you have any suggestions or improvements, please submit a pull request to the RomM docs.

    "},{"location":"System-Setup/Unraid-Compose-Setup/","title":"With Docker Compose","text":""},{"location":"System-Setup/Unraid-Compose-Setup/#prerequisites","title":"Prerequisites","text":"

    Before getting started, install the Community Apps plugin for Unraid.

    Install Docker Compose Addon from the CA (Community Apps Store)

    "},{"location":"System-Setup/Unraid-Compose-Setup/#docker-tab","title":"Docker Tab","text":"

    You will now see Compose option under the Docker Containers in your Docker Tab in Unraid

    "},{"location":"System-Setup/Unraid-Compose-Setup/#installation","title":"Installation","text":"

    Click Add New Stack

    Warning

    You need to make sure you are following either Folder Structure A or B (Recommend A Type) RomM Folder Structure

    Warning

    It's strongly recommended to backup the appdata folder (or mount it in a safe location) before updating, since tearing down the container will wipe the resources (covers, screenshots, etc.)

    "},{"location":"System-Setup/Unraid-Compose-Setup/#finish","title":"Finish","text":"

    Grab IP:Port from romm, and open tab in browser in http://IP:Port and it should take you to setup screen

    "},{"location":"System-Setup/Unraid-Setup-Guide/","title":"Unraid Setup Guide","text":""},{"location":"System-Setup/Unraid-Setup-Guide/#prerequisites","title":"Prerequisites","text":"

    Before getting started, install the Community Apps plugin for Unraid.

    "},{"location":"System-Setup/Unraid-Setup-Guide/#docker-network","title":"Docker network","text":"

    You'll want to create a custom bridge-type network for both containers to communicate with each other. This will prevent a number of common issues Unraid users tend to come across during setup. This can be done with the following command: docker network create romm, and you can verify it worked with docker network ls.

    "},{"location":"System-Setup/Unraid-Setup-Guide/#mariadb","title":"MariaDB","text":"

    MariaDB is required to run RomM, so install it from the plugin registry. Only the official and linuxserver versions are supported, but the official version is preferred.

    Now fill in all the environment variables; descriptions of the options and sensible defaults are listed in the example docker-compose.yml file.

    Warning

    The network type must be set to Custom: romm

    "},{"location":"System-Setup/Unraid-Setup-Guide/#installation","title":"Installation","text":"

    From the Unraid dashboard, click APPS in the navigation bar. In the search bar, search for romm, and install the app listed as \"OFFICIAL\". This one is maintained by our team and is the most up-to-date.

    "},{"location":"System-Setup/Unraid-Setup-Guide/#configuration","title":"Configuration","text":"

    Configure the required environment variables, ports and paths as per the example docker-compose.yml file.

    Warning

    The network type must also be set to Custom: romm

    Apply the changes, then head to the DOCKER tab. You should see both containers in a running state, and can access RomM using the IP:PORT of the container (highlighted below).

    Warning

    It's strongly recommended to backup the appdata folder (or mount it in a safe location) before updating, since tearing down the container will wipe the resources (covers, screenshots, etc.)

    "},{"location":"System-Setup/Unraid-Setup-Guide/#video-tutorial","title":"Video tutorial","text":"

    DemonWarriorTech has published How to Install RomM on Unraid (Beginner Friendly) on installing and running RomM on Unraid for Beginners with an in depth instructions and explanation of the software install and how to use it.

    AlienTech42 has published a great video on installing and running RomM on Unraid. While a bit out of date vis-a-vis install instructions, it's still very useful for general setup and debugging. Check it out!

    "},{"location":"System-Setup/Unraid-Setup-Guide/#unraid-community-support","title":"Unraid community support","text":"

    You can find a support thread in the unraid forums.

    "},{"location":"System-Setup/Unraid-Setup-Guide/#shout-outs","title":"Shout-outs","text":"

    We want to give a special shout-out to @Smurre95 and @sfumat0 for their help documenting this process, and working towards getting RomM listed in CA. \ud83e\udd1d

    "},{"location":"Tools/Igir-Collection-Manager/","title":"Igir Collection Manager","text":"

    Igir is a zero-setup ROM collection manager that sorts, filters, extracts or archives, patches, and reports on collections of any size on any OS. It can be used to rename your ROMs to match the RomM database, and to move them into a new directory structure.

    "},{"location":"Tools/Igir-Collection-Manager/#setup","title":"Setup","text":""},{"location":"Tools/Igir-Collection-Manager/#directory-structure","title":"Directory structure","text":"

    The directory structure is important for running the bulk ROM renaming script. Before running the bulk ROM renaming script, set up your directories as follows:

    .\n\u251c\u2500\u2500 dats/ # DAT files from no-intro.org\n\u251c\u2500\u2500 roms/ # Original ROM collection\n\u251c\u2500\u2500 roms-unverified/ # Working copy of ROMs\n\u2514\u2500\u2500 igir-romm-cleanup.sh\n
    "},{"location":"Tools/Igir-Collection-Manager/#initial-setup-steps","title":"Initial Setup Steps","text":"
    1. Create a working copy of your ROMs:

      cp -r roms/ roms-unverified/\n

      This provides a safe working environment and allows for easy script adjustment if needed.

    2. Download DAT Files:

      Extract the DAT files to your dats directory. You can optionally extract a subset of the .dat files into the directory instead.

    "},{"location":"Tools/Igir-Collection-Manager/#configuration","title":"Configuration","text":"

    Create the cleanup script igir-romm-cleanup.sh with the contents below:

    #!/usr/bin/env bash\nset -ou pipefail\ncd \"$(dirname \"${0}\")\"\n\nINPUT_DIR=roms-unverified\nOUTPUT_DIR=roms-verified\n\n# Documentation: https://igir.io/\n# Uses dat files: https://datomatic.no-intro.org/index.php?page=download&op=daily\ntime npx -y igir@latest \\\n  move \\\n  extract \\\n  report \\\n  test \\\n  -d dats/ \\\n  -i \"${INPUT_DIR}/\" \\\n  -o \"${OUTPUT_DIR}/{romm}/\" \\\n  --input-checksum-quick false \\\n  --input-checksum-min CRC32 \\\n  --input-checksum-max SHA256 \\\n  --only-retail\n

    Make the script executable:

    chmod a+x igir-romm-cleanup.sh\n
    "},{"location":"Tools/Igir-Collection-Manager/#usage","title":"Usage","text":""},{"location":"Tools/Igir-Collection-Manager/#run-the-script","title":"Run the script","text":"

    Run the script. It will generate a new output directory named roms-verified, moving the files from roms-unverified if its checksum matches any of the known checksums in the DAT files provided. Any ROMs not identified will remain in the roms-unverified directory.

    "},{"location":"Tools/Igir-Collection-Manager/#manually-move-over-remaining-files","title":"Manually move over remaining files","text":"

    The script may not identify all of the ROMs in your input directory. You can choose to migrate them over manually:

    npx -y igir@latest \\\n  move \\\n  -i roms-unverified/ \\\n  -o roms-verified/ \\\n  --dir-mirror\n

    This will move your ROMs from the input to the output directory, preserving the subdirectory structure. It also cleans up file extensions in the process.

    "},{"location":"Tools/Igir-Collection-Manager/#reorganize-multi-disc-games","title":"Reorganize multi-disc games","text":"

    The Igir script will move games that have multiple discs to separate folders. This can confuse RomM's game detection, and those games need to be reorganized into single folders with many discs.

    To do this enter your platform directory, such as ps or psx and run the following:

    ls -d *Disc* | while read dir; do\n  game=$(echo \"${dir}\" | sed -r 's/ \\(Disc [0-9]+\\)//')\n  mkdir -p \"${game}\"\n  mv \"${dir}\"/* \"${game}/\"\n  rm -rf \"${dir}\"\ndone\n

    This will find any directory with (Disc in the name and move the files into a new directory without the (Disc #) string. For example:

    Before:

    Final Fantasy VII (Disc 1) (USA)\nFinal Fantasy VII (Disc 2) (USA)\n

    Gets combined to:

    Final Fantasy VII (USA)\n
    "},{"location":"Troubleshooting/Authentication-Issues/","title":"Troubleshooting Authentication","text":""},{"location":"Troubleshooting/Authentication-Issues/#error-403-forbidden","title":"Error: 403 Forbidden","text":"

    When authentication is enabled, most endpoints will return a 403 Forbidden response if you're not authenticated, or if your sessions is in a broken state. The session key can be reset by clearing your cookies.

    CSRF protection is also enabled, which helps to mitigates CSRF attacks (useful if your instance is public). If you encounter a Forbidden (403) CSRF verification failed error, simply reloading your browser should force it to fetch a fresh CSRF cookie.

    "},{"location":"Troubleshooting/Authentication-Issues/#error-unable-to-login-csrf-token-verification-failed","title":"Error: Unable to login: CSRF token verification failed","text":"

    This error is known to happen on Chrome, but could happen in other browsers; manually clear your cookies (specifically one called csrftoken) and hard reload your browser window (CMD+SHIFT+R on macOS, CTRL+F5 on Windows).

    "},{"location":"Troubleshooting/Authentication-Issues/#error-400-bad-request-on-the-websocket-endpoint","title":"Error: 400 Bad Request on the Websocket endpoint","text":"

    If you're running RomM behind a reverse-proxy (Caddy, Nginx, etc.), ensure that Websockets are supported and enabled. This may vary depending on the reverse proxy solution being used. In the case of Nginx Proxy Manager, enable the \"Websockets Support\" toggle when editing the proxy host.

    "},{"location":"Troubleshooting/Kubernetes-Issues/","title":"Kubernetes Troubleshooting","text":""},{"location":"Troubleshooting/Kubernetes-Issues/#error-invalid-host-in-tcpinternal-ip8080-of-the-listen-directive-in-etcnginxconfddefaultconf7","title":"Error: invalid host in \"tcp://<internal ip>:8080\" of the \"listen\" directive in /etc/nginx/conf.d/default.conf:7","text":"

    By default, Kubernetes will grab information about the service object linked to a pod and inject it as an environment variable into the pod. In RomM, this leads to the pod attempting to bind to the service IP address, leading to the above fatal error.

    To resolve thes error, this default Kubernetes behaviour needs to be disabled by setting the enableServiceLinks value in the pod spec to false.

    apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: romm\n  namespace: romm\n  ...\nspec:\n  ...\n  template:\n    ...\n    spec:\n      enableServiceLinks: false\n      ...\n
    "},{"location":"Troubleshooting/Miscellaneous-Troubleshooting/","title":"Miscellaneous Troubleshooting","text":""},{"location":"Troubleshooting/Miscellaneous-Troubleshooting/#restarting-the-container-when-using-sqlite-drops-all-the-datarequires-a-full-re-scan","title":"Restarting the container when using SQLite drops all the data/requires a full re-scan","text":"

    Verify that the database is mapped to a persistent storage volume in your docker compose or Unraid template.

    \"/path/to/database:/romm/database\" # [Optional] Only needed if ROMM_DB_DRIVER=sqlite or not set\n
    "},{"location":"Troubleshooting/Miscellaneous-Troubleshooting/#error-could-not-get-twitch-auth-token-check-client_id-and-client_secret","title":"Error: Could not get twitch auth token: check client_id and client_secret","text":"

    This is likely due to mis-configured environment variables; verify that CLIENT_ID and CLIENT_SECRET are set correctly, and that both match the values in IGDB.

    "},{"location":"Troubleshooting/Miscellaneous-Troubleshooting/#how-to-view-romm-logs-to-assist-with-troubleshooting","title":"How to view RomM logs to assist with troubleshooting","text":"

    Each platform may have different logs, but check the stdout logs for docker. For example when using the recommended docker compose setup docker logs -f romm will display a continuous stream of the log. Most lines start with INFO, WARNING, or ERROR

    "},{"location":"Troubleshooting/Scanning-Issues/","title":"Troubleshooting Scanning","text":""},{"location":"Troubleshooting/Scanning-Issues/#scan-is-skipping-all-platformsends-instantly","title":"Scan is skipping all platforms/ends instantly","text":"

    There are a few common reasons why a scan may end instantly/without scanning platforms

    "},{"location":"Troubleshooting/Scanning-Issues/#roms-not-found-for-platform-x-check-romm-folder-structure","title":"ROMs not found for platform X, check romm folder structure","text":"

    This is the same issue as the one above, and can be quickly solved by verifying your folder structure. RomM expects a library with a folder named roms in it, for example:

    "},{"location":"Troubleshooting/Scanning-Issues/#scan-does-not-recognize-a-platform","title":"Scan does not recognize a platform","text":"

    When scanning the folders mounted in /library/roms, the scanner tries to match the folder name with the platform's slug in IGDB. If you notice that the scanner isn't detecting a platform, verify that the folder name matches the slug in the URL of the platform in IGDB. For example, the Nintendo 64DD has the URL https://www.igdb.com/platforms/64dd, so the folder should be named 64dd.

    "},{"location":"Troubleshooting/Scanning-Issues/#scan-times-out-after-4-hours","title":"Scan times out after ~4 hours","text":"

    The background scan task times out after 4 hours, which can happen if you have a very large library. The easiest work around is to keep running scans every 4 hours, without checking the \"Complete re-scan\" option. You can also change the timeout via environment variable SCAN_TIMEOUT.

    "},{"location":"Troubleshooting/Scanning-Issues/#scan-stops-before-finishing-a-platform","title":"Scan stops before finishing a platform","text":"

    Check the logs for RomM, you should find a line that looks like ERROR: [RomM][scan_handler][2025-04-12 11:48:55] that explains why the scanner stopped. This can often happen due to a corrupted file or a file the python zipfile library cannot handle, such as old DOS zip files with backslashes instead of forward slashes.

    "},{"location":"Troubleshooting/Scanning-Issues/#when-scanning-a-very-large-library-with-many-platforms-it-is-difficult-to-keep-track-of-which-systems-have-scanned-in","title":"When scanning a very large library with many platforms it is difficult to keep track of which systems have scanned in","text":"

    The easiest method is to check the logs via this command, which will list all the scanned platforms since the RomM container was started docker logs romm 2>/dev/null|egrep 'scan_handler.*Identified as.*\ud83c\udfae'

    Here is an example output:

    $ docker logs romm 2>/dev/null|egrep 'scan_handler.*Identified as.*\ud83c\udfae'\nINFO:     [RomM][scan_handler][2025-04-12 11:37:40]   Identified as PlayStation \ud83c\udfae\nINFO:     [RomM][scan_handler][2025-04-12 14:39:32]   Identified as DOS \ud83c\udfae\nINFO:     [RomM][scan_handler][2025-04-13 12:50:42]   Identified as WonderSwan \ud83c\udfae\n
    "},{"location":"Troubleshooting/Synology-Issues/","title":"Troubleshooting Synology","text":""},{"location":"Troubleshooting/Synology-Issues/#errno-13-access-denied","title":"ErrNo 13: Access Denied","text":"

    We have noticed recently a spate of access denied on Synology systems via Portainer or even docker manager. The ErrNo13 is directly related to Synology and it is a simple permission issue. To fix it please do the following:

    1. Make sure SSH is enabled on your Synology product. Refer to here if it is not Enable SSH
    2. Connect to SSH and login as your admin username and password (Same login used to login to DSM web page)
    3. Take a note on your user:group you can find this by typing ID when logged into SSH.
    4. Type the following commands in the SSH window.

    sudo chown -R user:group /path/to/library

    sudo chmod -R a=,a+rX,u+w,g+w /path/to/library

    sudo chown -R user:group /path/to/assets

    sudo chmod -R a=,a+rX,u+w,g+w /path/to/assets

    sudo chown -R user:group /path/to/config

    sudo chmod -R a=,a+rX,u+w,g+w /path/to/config

    You will find the relevant directories in your compose, this is basically the folders where you store your RomM information and we are just resetting permissions. Restart the containers and you should now have no issues scanning information in!

    Any issues please ask in the Discord.

    Thanks to Docker IDs - DrFrankenstein for the guidance from his blog.

    "},{"location":"Usage/Administration/","title":"Administration","text":"

    Clicking on your Profile icon from any screen opens the Administration Drawer. This drawer will look slightly different based on your role. The options available can include Profile, User Interface, Library Management, Administration, Server Stats, and About.

    "},{"location":"Usage/Administration/#profile","title":"Profile","text":"

    All users can access this screen. From here you can change your username, password, and email.

    Additionally, you can submit your RetroAchievements username and synchronize your achievements here.

    "},{"location":"Usage/Administration/#user-interface","title":"User Interface","text":"

    From here you can:

    "},{"location":"Usage/Administration/#library-management","title":"Library Management","text":"

    From this screen you can:

    "},{"location":"Usage/Administration/#administration","title":"Administration","text":"

    From this page you can manage users and check scheduled and manual tasks.

    "},{"location":"Usage/Administration/#server-stats","title":"Server Stats","text":"

    This area displays the number of platforms, games, saves, states, and screenshots on the server, as well as how much disk space this consumes. Platforms can be filtered here to show how much each platform contributes to total size and game count.

    "},{"location":"Usage/Administration/#about","title":"About","text":"

    This pop-up displays your RomM version with links to the community Discord, GitHub, and documentation.

    "},{"location":"Usage/LibraryManagement/","title":"Library Management","text":""},{"location":"Usage/LibraryManagement/#the-library-view","title":"The Library View","text":"

    The default library view shows a few ribbons: Recently Added, Continue Playing, Platforms, and Collections. Games and Platforms are presented as cards that can be interacted with.

    The menu bar is constantly visible and includes tools to Search, List Platforms, Manage Collections, Scan, go into Console Mode, and Upload content as well as access your administration panel.

    In all views, a grid icon is present in the upper right of the screen or container. This can be toggled to collapse or expand the container.

    "},{"location":"Usage/LibraryManagement/#game-and-platform-cards","title":"Game and Platform cards","text":"

    Platform cards can be clicked to go directly to the platform. A game card can be interacted with in several ways: putting your mouse over it allows you to download the game, play the game if the system is supported, or open a context menu giving you the option to manually match game information using a metadata agent, edit existing data, refresh the metadata, and add or remove the game from favourites or collections.

    Clicking a platform will take you to the platform view, while clicking a game will take you to the game view.

    "},{"location":"Usage/LibraryManagement/#filters","title":"Filters","text":"

    Filters are present on nearly every screen in RomM, allowing you to quickly drill down to see only the information relevant to your search.

    If you perform a search first, the listed filters will be taken from the metadata of all present games. For example, if you searched for the word \"Fox\", and then clicked filters and selected a Language, the list of languages available will be taken from the displayed games.

    "},{"location":"Usage/LibraryManagement/#toggles","title":"Toggles","text":"

    The filters that can be toggled include:

    Next there is a platform dropdown. This allows you to select a platform you want to restrict your view to showing.

    After this you can filter by metadata: Game Genre, Franchise, Collections, Company, Age Rating, Region, and Language. One additional filter exists after these: Status. This allows you to use the \"personal\" data tab on any game to track your progress of the game (never played, backlogged, complete, etc).

    "},{"location":"Usage/LibraryManagement/#the-menu-bar","title":"The Menu bar","text":"

    The menu bar is designed for quick access to the tools of your RomM server.

    "},{"location":"Usage/LibraryManagement/#search","title":"Search","text":"

    Simply typing text into the search bar will bring up game cards for each game that matches the query. To the left of the search bar are two icons: the view filters and the new collection button.

    "},{"location":"Usage/LibraryManagement/#list-platforms","title":"List Platforms","text":"

    The Platforms button opens a drawer listing all of the known platforms in RomM. Clicking on any of these will create a search that is limited to that platform.

    "},{"location":"Usage/LibraryManagement/#collections","title":"Collections","text":"

    The Collections button opens a drawer listing all of your manually created collections which is specific to each user, as well as your autogenerated collections created by RomM. Clicking a collection will take you to the collection view.

    "},{"location":"Usage/LibraryManagement/#scan","title":"Scan","text":"

    This is where you'll scan for new platforms and games. Metadata sources can be selected to determine which providers will be used to fetch metadata. Use the Platforms dropdown to restrict your scan to specific platforms.

    The Scan options dropdown allows you to choose a specific type of scan to perform:

    "},{"location":"Usage/LibraryManagement/#console","title":"Console","text":"

    This button will take you to a new full screen UI that's especially good for navigation with a controller.

    "},{"location":"Usage/LibraryManagement/#upload","title":"Upload","text":"

    This button allows you to upload games directly to RomM from the user interface. Simply select a platform and then either click to browse to a ROM or drag and drop it onto the interface.

    "},{"location":"Usage/LibraryManagement/#recently-added","title":"Recently Added","text":"

    After a scan is performed, the most recently added games can be found on this ribbon.

    "},{"location":"Usage/LibraryManagement/#continue-playing","title":"Continue Playing","text":"

    After a game has been played for any amount of time, it's added to this row. The context menu gains a new option for games located on this ribbon: remove from playing. This helps prevent the ribbon from being cluttered by games you wanted to test but do not plan on playing long term.

    "},{"location":"Usage/LibraryManagement/#platforms","title":"Platforms","text":"

    The list of platforms presented here will be matched by RomM by directory structure. See Supported Platforms page for more information about naming your directories.

    "},{"location":"Usage/LibraryManagement/#favourites-and-collections","title":"Favourites and Collections","text":"

    This ribbon contains all the games you've marked as favourites, and any collections you've created or that have been generated by RomM.

    "},{"location":"Usage/LibraryManagement/#platform-view","title":"Platform View","text":"

    The platform view shows all of the games for a specific platform. There is a button to show the platform drawer, the platform firmware, as well as the usual filter button.

    "},{"location":"Usage/LibraryManagement/#platform-drawer","title":"Platform Drawer","text":"

    The platform view drawer has a large icon representing the platform, along with its title.

    Below that is a button to upload ROMs and a button to initiate scans.

    Below that is a line showing how many metadata providers are being used for that platform.

    Next comes all the metadata for the platform itself: the name, folder name, category, generation, and so on.

    Following that are the platform settings, which consists of the style of cover used in the game cards for that platform.

    Finally, in the Danger Zone, is a Delete Platform button. This removes the platform from the database, it does NOT touch the files on your system. If you delete a platform in this way, scanning for new platforms will restore it, and all games will have to have their metadata re-matched.

    "},{"location":"Usage/LibraryManagement/#firmware","title":"Firmware","text":"

    Next to the platform drawer button is the firmware button. This allows you to review all of the firmware for that system, and upload firmware using the user interface.

    Uploading firmware will open a file browse dialog box. Simply select the BIOS file or files you wish to upload and click \"Upload\".

    "},{"location":"Usage/LibraryManagement/#collection-view","title":"Collection View","text":"

    The Collection View is similar to the Platform View. It has a Platform drawer next to the filters, much like how the Platform View has the Platform Drawer, but lacks the Firmware button.

    The Collection metadata will be shown, which includes a game count, who owns the collection, the privacy of the collection, and the ability to delete the collection.

    "},{"location":"Usage/LibraryManagement/#game-view","title":"Game View","text":"

    The game view is broken down into two distinct parts.

    The first container is the poster, with the usual download, play (if the system allows for playing in a web browser) and context menu as well as a new button: copy download link.

    The second container is the game tabs: Details, Game Data, and Personal tabs. These are containers for information about the game, how RomM sees the save data, and your personal notes. Additional tabs may be visible here depending on your configuration, including the Game Manual, data from How Long to Beat, screenshots, as well as related games. The Details tab includes metadata for the game. This will show where the data comes from, the platform and year of release, as well as the file information like regions and collections. This is the information that is used for filtering.

    The Game Data tab includes save files and save states, the ability to upload and download them, as well as delete them. This data is personal to the logged in user.

    Finally the Personal tab has check boxes denoting if a game is backlogged, being played, or if it should be hidden. User data such as rating, difficulty, % completed, and the status of the game can also be set here. RetroAchievements can be viewed from this tab for supported matched games.

    If How Long To Beat is enabled as a metadata provider, there will also be a tab here for viewing that data as well.

    "},{"location":"Usage/UserManagement/","title":"User Management","text":"

    The Administration panel contains the tools used to manage users on the server. The first user created will always be given the admin role.

    Users can manage their own game saves, save states, their profile icon, and the \"Personal\" data tab on games.

    "},{"location":"Usage/UserManagement/#adding-users","title":"Adding Users","text":"

    Adding a user is as simple as providing a username, password, email address, and selecting a role. Users can be added manually using the \"Add\" button or by inviting a user via link. When inviting a user, you only need to set a role; they will be prompted to complete the rest of the information.

    "},{"location":"Usage/UserManagement/#roles-explained","title":"Roles Explained","text":"

    Admin - The highest authority role. This grants full permission to do everything on the server.

    Editor - Can edit platforms and games (adding, removing, or scanning for new content) and make collections public.

    Viewer - The most restricted role. Can play games and interact with the Personal data tab.

    "},{"location":"Usage/UserManagement/#removing-users","title":"Removing Users","text":"

    Removing a user is as simple as clicking the red delete icon and confirming the operation.

    "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Introduction","text":"

    Welcome to the RomM Project, the premier self-hosted, open source ROM manager.

    Website | Demo

    RomM (ROM Manager) allows you to scan, enrich, and browse your game collection with a clean and responsive interface. With support for multiple platforms, various naming schemes, and custom tags, RomM is a must-have for anyone who plays on emulators.

    To get started with RomM, head over to the Quick Start guide.

    "},{"location":"#philosophy","title":"Philosophy","text":"

    At the heart of this project is a commitment to freedom, collaboration, and transparency. We believe that software should be built for the benefit of its users, rather than solely to maximize profit or serve the interests of a few stakeholders, ensuring that it doesn't manipulate, exploit, or prioritize data collection.

    By offering RomM as a self-hosted, open-source solution, we ensure that everyone has the ability to manage their game collections on their own terms, and own their data, all without being tied to proprietary systems or services.

    Rom is and will always be free and open-source software.

    The core app is licensed under GNU AGPLv3, which requires that all modifications to the code be made available under the same license. This ensures that the community can benefit from and build upon the contributions of others, promoting trust and transparency.

    Other projects under the umbrella will be licensed under similar permissive licenses, such as GNU GPLv3 for software, or CC0 for documentation.

    "},{"location":"#contributing","title":"Contributing","text":"

    RomM is a collaborative project, and we welcome contributions from the community. Our code is available on GitHub, and we encourage you to contribute to the project by submitting bug reports, feature requests, or pull requests. Please check the contribution guidelines in each project for more information.

    "},{"location":"#community","title":"Community","text":"

    We strive to create a safe and respectful space where everyone can contribute and benefit from the project by fostering a welcoming and inclusive environment for all users, regardless of their background or identity.

    Join us on Discord, where you can ask questions, submit ideas, get help, showcase your collection, and discuss RomM with other users.

    "},{"location":"API-and-Development/API-Reference/","title":"API Reference","text":""},{"location":"API-and-Development/API-Reference/#api-reference","title":"API Reference","text":"

    RomM provides a comprehensive REST API that allows you to programmatically interact with your RomM instance. Most API endpoints are authenticated and follow RESTful conventions.

    "},{"location":"API-and-Development/API-Reference/#interactive-documentation","title":"Interactive Documentation","text":"

    RomM automatically generates interactive API documentation using OpenAPI (Swagger). You can access the interactive API docs directly from your running instance:

    These interactive docs allow you to:

    "},{"location":"API-and-Development/API-Reference/#base-url","title":"Base URL","text":"

    The API base URL is typically:

    http://your-instance:3000/api\n

    Replace your-instance with your actual RomM instance URL or IP address.

    "},{"location":"API-and-Development/API-Reference/#authentication","title":"Authentication","text":"

    All API endpoints require authentication. RomM supports:

    When using OAuth2, you'll need to obtain a token from /api/token endpoint and include it in the Authorization header as Bearer <token>.

    "},{"location":"API-and-Development/API-Reference/#oauth2-scopes","title":"OAuth2 Scopes","text":"

    The API uses OAuth2 scopes to control access to different resources:

    Read Scopes:

    Write Scopes:

    "},{"location":"API-and-Development/API-Reference/#api-endpoints-overview","title":"API Endpoints Overview","text":"

    The RomM API provides comprehensive endpoints for managing all aspects of your ROM collection:

    "},{"location":"API-and-Development/API-Reference/#core-resources","title":"Core Resources","text":""},{"location":"API-and-Development/API-Reference/#supporting-features","title":"Supporting Features","text":"

    For complete endpoint documentation including request/response schemas, query parameters, and authentication requirements, visit the interactive API documentation at /api/docs or /api/redoc on your RomM instance.

    "},{"location":"API-and-Development/API-Reference/#example-usage","title":"Example Usage","text":""},{"location":"API-and-Development/API-Reference/#using-curl","title":"Using cURL","text":"
    # Get all libraries\ncurl -u username:password http://your-instance:3000/api/libraries\n\n# Get a specific ROM\ncurl -u username:password http://your-instance:3000/api/roms/123\n\n# Create a new ROM entry\ncurl -X POST -u username:password \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\": \"New ROM\", \"platform_id\": 1}' \\\n  http://your-instance:3000/api/roms\n
    "},{"location":"API-and-Development/API-Reference/#using-python","title":"Using Python","text":"
    import requests\nfrom requests.auth import HTTPBasicAuth\n\n# Setup authentication\nauth = HTTPBasicAuth('username', 'password')\nbase_url = 'http://your-instance:3000/api'\n\n# Get all libraries\nresponse = requests.get(f'{base_url}/libraries', auth=auth)\nlibraries = response.json()\n\n# Get a specific ROM\nresponse = requests.get(f'{base_url}/roms/123', auth=auth)\nrom = response.json()\n
    "},{"location":"API-and-Development/API-Reference/#using-javascriptnodejs","title":"Using JavaScript/Node.js","text":"
    const axios = require(\"axios\");\n\n// Setup authentication\nconst api = axios.create({\n    baseURL: \"http://your-instance:3000/api\",\n    auth: {\n        username: \"username\",\n        password: \"password\",\n    },\n});\n\n// Get all libraries\nconst libraries = await api.get(\"/libraries\");\n\n// Get a specific ROM\nconst rom = await api.get(\"/roms/123\");\n
    "},{"location":"API-and-Development/API-Reference/#openapi-specification","title":"OpenAPI Specification","text":"

    You can download the complete OpenAPI specification from your RomM instance:

    http://your-instance:3000/openapi.json\n

    This specification can be imported into API testing tools like Postman, used to generate client libraries, or used for API mocking.

    "},{"location":"API-and-Development/API-Reference/#getting-help","title":"Getting Help","text":"

    For API-specific questions or issues:

    1. Check the interactive documentation at /api/docs or /api/redoc on your instance
    2. Review the code in the RomM repository
    3. Open an issue on GitHub
    4. Join the Discord community
    "},{"location":"API-and-Development/Contributing/","title":"Contributing","text":""},{"location":"API-and-Development/Contributing/#contributing-to-romm","title":"Contributing to RomM","text":"

    Thank you for considering contributing to RomM! This document outlines some guidelines to help you get started with your contributions.

    If you're looking to implement a large feature or make significant changes to the project, it's best to open an issue first AND join the Discord to discuss your ideas with the maintainers.

    "},{"location":"API-and-Development/Contributing/#code-of-conduct","title":"Code of Conduct","text":"

    Please note that this project adheres to the Contributor Covenant code of conduct. By participating in this project, you are expected to uphold this code.

    "},{"location":"API-and-Development/Contributing/#ai-assistance-notice","title":"AI Assistance Notice","text":"

    [!IMPORTANT]

    If you are using any kind of AI assistance to contribute to RomM, it must be disclosed in the pull request.

    If you are using any kind of AI assistance while contributing to RomM this must be disclosed in the pull request, along with the extent to which AI assistance was used (e.g. docs only vs. code generation). If PR responses are being generated by an AI, disclose that as well. As a small exception, trivial tab-completion doesn't need to be disclosed.

    An example disclosure:

    This PR was written primarily by Claude Code.

    Or a more detailed disclosure:

    I consulted ChatGPT to understand the codebase but the solution was fully authored manually by myself.

    Failure to disclose this is rude to the human operators on the other end of the pull request, but it also makes it difficult to determine how much scrutiny to apply to the contribution.

    In a perfect world, AI assistance would produce equal or higher quality work than any human. That isn't the world we live in today, and in most cases it's generating slop.

    Please be respectful to maintainers and disclose AI assistance.

    "},{"location":"API-and-Development/Contributing/#contributing-to-the-docs","title":"Contributing to the Docs","text":"

    If you would like to contribute to the project's documentation, open a pull request against the docs repo. We welcome any contributions that help improve the documentation (new pages, updates, or corrections).

    "},{"location":"API-and-Development/Contributing/#adding-translations","title":"Adding Translations","text":"

    If you would like to translate the project into another language, create a new folder under the frontend/src/locales directory, and follow the existing language files as a template. Once you've created the new language file, open a pull request to add it to the project.

    "},{"location":"API-and-Development/Contributing/#how-to-contribute-code","title":"How to Contribute Code","text":"
    1. Fork the repository.
    2. Clone your forked repository: git clone https://github.com/your-username/romm.git
    3. Checkout the master branch: git checkout master
    4. Follow the steps in the developer setup guide
    5. Create a new branch for your feature/fix: git checkout -b feature-or-fix-name
    6. Make your changes and commit them with descriptive commit messages: git commit -am 'Add feature XYZ'
    7. Push your changes to your fork: git push origin feature-or-fix-name
    8. Open a pull request to the master branch of the original repository.
    "},{"location":"API-and-Development/Contributing/#pull-request-guidelines","title":"Pull Request Guidelines","text":""},{"location":"API-and-Development/Contributing/#code-style","title":"Code Style","text":"

    Follow the existing code style used throughout the project. If working with VSCode or a similar editor, consider installing these extensions:

    "},{"location":"API-and-Development/Contributing/#issue-reporting","title":"Issue Reporting","text":"

    If you encounter any bugs or have suggestions for improvements, please create an issue on GitHub. Provide as much detail as possible, including steps to reproduce the issue if applicable.

    "},{"location":"API-and-Development/Contributing/#licensing","title":"Licensing","text":"

    By contributing to RomM, you agree that your contributions will be licensed under the project's LICENSE.

    Thank you for contributing to RomM! Your help is greatly appreciated.

    "},{"location":"API-and-Development/Development-Setup/","title":"Development Setup","text":""},{"location":"API-and-Development/Development-Setup/#setting-up-romm-for-development","title":"Setting up RomM for development","text":""},{"location":"API-and-Development/Development-Setup/#option-1-using-docker","title":"Option 1: Using Docker","text":"

    If you prefer to use Docker for development, you can set up RomM using the provided Docker Compose configuration. This method simplifies the setup process by encapsulating all dependencies within Docker containers.

    "},{"location":"API-and-Development/Development-Setup/#environment-setup","title":"Environment setup","text":""},{"location":"API-and-Development/Development-Setup/#create-the-mock-structure-with-at-least-one-rom-and-empty-config-for-manual-testing","title":"Create the mock structure with at least one rom and empty config for manual testing","text":"
    mkdir -p romm_mock/library/roms/switch\ntouch romm_mock/library/roms/switch/metroid.xci\nmkdir -p romm_mock/resources\nmkdir -p romm_mock/assets\nmkdir -p romm_mock/config\ntouch romm_mock/config/config.yml\n
    "},{"location":"API-and-Development/Development-Setup/#copy-envtemplate-to-env-and-fill-the-variables","title":"Copy env.template to .env and fill the variables","text":"
    cp env.template .env\n
    ROMM_BASE_PATH=/app/romm\nDEV_MODE=true\n
    "},{"location":"API-and-Development/Development-Setup/#build-the-image","title":"Build the image","text":"
    docker compose build  # or `docker compose build --no-cache` to rebuild from scratch\n
    "},{"location":"API-and-Development/Development-Setup/#spin-up-the-docker-containers","title":"Spin up the Docker containers","text":"
    docker compose up -d\n

    And you're done! You can access the app at http://localhost:3000. Any changes made to the code will be automatically reflected in the app thanks to the volume mounts.

    "},{"location":"API-and-Development/Development-Setup/#option-2-manual-setup","title":"Option 2: Manual setup","text":""},{"location":"API-and-Development/Development-Setup/#environment-setup_1","title":"Environment setup","text":""},{"location":"API-and-Development/Development-Setup/#-create-the-mock-structure-with-at-least-one-rom-and-empty-config-for-manual-testing","title":"- Create the mock structure with at least one rom and empty config for manual testing","text":"
    mkdir -p romm_mock/library/roms/switch\ntouch romm_mock/library/roms/switch/metroid.xci\nmkdir -p romm_mock/resources\nmkdir -p romm_mock/assets\nmkdir -p romm_mock/config\ntouch romm_mock/config/config.yml\n
    "},{"location":"API-and-Development/Development-Setup/#-copy-envtemplate-to-env-and-fill-the-variables","title":"- Copy env.template to .env and fill the variables","text":"
    cp env.template .env\n
    "},{"location":"API-and-Development/Development-Setup/#-install-system-dependencies","title":"- Install system dependencies","text":"
    # https://mariadb.com/docs/skysql-previous-release/connect/programming-languages/c/install/#Installation_via_Package_Repository_(Linux):\nsudo apt install libmariadb3 libmariadb-dev libpq-dev\n\n# Build and configure RAHasher (optional)\n# This is only required to calculate RA hashes\n# Users on macOS can skip this step as RAHasher is not supported\ngit clone --recursive https://github.com/RetroAchievements/RALibretro.git\ncd ./RALibretro\ngit checkout 1.8.0\ngit submodule update --init --recursive\nsed -i '22a #include <ctime>' ./src/Util.h\nmake HAVE_CHD=1 -f ./Makefile.RAHasher\ncp ./bin64/RAHasher /usr/bin/RAHasher\n
    "},{"location":"API-and-Development/Development-Setup/#-install-python-dependencies","title":"- Install python dependencies","text":"

    You'll need uv installed

    https://docs.astral.sh/uv/getting-started/installation/

    curl -LsSf https://astral.sh/uv/install.sh | sh\n

    Then create the virtual environment and install the dependencies using uv:

    uv venv\nsource .venv/bin/activate\nuv sync --all-extras --dev\n
    "},{"location":"API-and-Development/Development-Setup/#-spin-up-the-database-and-other-services","title":"- Spin up the database and other services","text":"
    docker compose up -d\n
    "},{"location":"API-and-Development/Development-Setup/#-run-the-backend","title":"- Run the backend","text":"

    Migrations will be run automatically when running the backend.

    cd backend\nuv run python3 main.py\n
    "},{"location":"API-and-Development/Development-Setup/#setting-up-the-frontend","title":"Setting up the frontend","text":""},{"location":"API-and-Development/Development-Setup/#-install-nodejs-dependencies","title":"- Install node.js dependencies","text":"
    cd frontend\n# npm version >= 9 needed\nnpm install\n
    "},{"location":"API-and-Development/Development-Setup/#-create-symlink-to-library-and-resources","title":"- Create symlink to library and resources","text":"
    mkdir assets/romm\nln -s ../romm_mock/resources assets/romm/resources\nln -s ../romm_mock/assets assets/romm/assets\n
    "},{"location":"API-and-Development/Development-Setup/#-run-the-frontend","title":"- Run the frontend","text":"
    npm run dev\n
    "},{"location":"API-and-Development/Development-Setup/#setting-up-the-linter","title":"Setting up the linter","text":"

    We use Trunk for linting, which combines multiple linters and formatters with sensible defaults and a single configuration file. You'll need to install the Trunk CLI to use it.

    "},{"location":"API-and-Development/Development-Setup/#-install-the-trunk-cli","title":"- Install the Trunk CLI","text":"
    curl https://get.trunk.io -fsSL | bash\n

    Alternative installation methods can be found in their docs. On commit, the linter will run automatically. To run it manually, use the following commands:

    trunk fmt\ntrunk check\n

    Failing to install and run the linter will result in a failed CI check, which won't allow us to merge your PR.

    "},{"location":"API-and-Development/Development-Setup/#test-setup","title":"Test setup","text":""},{"location":"API-and-Development/Development-Setup/#-create-the-test-user-and-database-with-root-user","title":"- Create the test user and database with root user","text":"
    docker exec -i romm-db-dev mariadb -uroot -p<root password> < backend/romm_test/setup.sql\n
    "},{"location":"API-and-Development/Development-Setup/#-run-tests","title":"- Run tests","text":"

    Migrations will be run automatically when running the tests.

    cd backend\n# path or test file can be passed as argument to test only a subset\nuv run pytest [path/file]\n# or run the following command to run all tests\n# the -vv switch increases the verbosity of the output, providing more detailed information during test execution.\nuv run pytest -vv\n
    "},{"location":"Getting-Started/Authentication/","title":"Authentication","text":"

    RomM provides support for various forms of authentication, granting flexibility in securing access to its features.

    "},{"location":"Getting-Started/Authentication/#setup","title":"Setup","text":"

    You'll want to set the following environment variable before starting RomM:

    "},{"location":"Getting-Started/Authentication/#sessions","title":"Sessions","text":"

    When the /login endpoint is called with valid credentials, a session_id is generated, stored as a cookie and sent to the browser. The same token is used to create a cache entry in Valkey (or in-memory if Valkey is disabled) which maps the token to the user. This way no sensitive information is stored on the client.

    "},{"location":"Getting-Started/Authentication/#roles","title":"Roles","text":"

    A user can have one of the following roles:

    As permissions are additive, editors will have all permissions of the viewer role, and admins all those of the editor role.

    "},{"location":"Getting-Started/Authentication/#basic-authentication","title":"Basic Authentication","text":"

    Requests can be made to protected API endpoints with an authorization header. The token is the base64 encoded value of username:password.

    Example using cURL:

    curl https://romm.local/api/platforms -H 'Authorization: Basic YWRtaW46aHVudGVyMg=='\n
    "},{"location":"Getting-Started/Authentication/#oauth","title":"OAuth","text":"

    Along with the above forms of authentication, we've added an endpoint to generate expiring, scope-limited authentication tokens (/api/token). Successfully authenticating with that endpoint with return an access_token valid for 15 minutes, and a refresh_token valid for 2 weeks. The refresh_token can be used to generate a new access_token when needed.

    The /api/token endpoint requires a username, password, and a list of scopes in the format read:roms write:roms read:platforms .... The list of scopes and endpoints are available to browse via Swagger UI or ReDoc (see next section).

    Note: As of now, only the legacy password grant type is supported. We plan to eventually add support for Client Credentials.

    "},{"location":"Getting-Started/Authentication/#openapi","title":"OpenAPI","text":"

    The API endpoints are fully documented and compliant with the OpenAPI specification. Explore the API endpoints using the Swagger UI interface at /api/docs and the ReDoc interface at /api/redoc, or view the raw JSON at /openapi.json.

    For more information on OpenAPI, visit the OpenAPI Specification website.

    "},{"location":"Getting-Started/Authentication/#faq","title":"FAQ","text":""},{"location":"Getting-Started/Authentication/#can-i-disable-authentication","title":"Can I disable authentication?","text":"

    No, authentication is required and enabled by default.

    "},{"location":"Getting-Started/Authentication/#i-want-to-allow-an-editor-to-edit-roms-but-not-delete-them-can-i-do-that","title":"I want to allow an EDITOR to edit ROMs but not delete them. Can I do that?","text":"

    At this time, fine-grain control over permissions within a role is not supported. This decision was taking in order to simplify user management in the client, and authentication/permission code on the server.

    "},{"location":"Getting-Started/Authentication/#is-authentication-saferobust-can-i-trust-it","title":"Is authentication safe/robust? Can I trust it?","text":"

    We've done our best to build an authentication system that is simple, clear and comprehensible. We have automated tests which verify that access is granted when it should be, and blocked when not (invalid credentials, missing permissions, expired access tokens, etc.). That being said, we welcome any reviews of our authentication and permission flows, PRs to fix issues, and new tests to cover edge cases.

    "},{"location":"Getting-Started/Authentication/#i-found-an-bugissue-with-authentication-how-do-i-report-it","title":"I found an bug/issue with authentication. How do I report it?","text":"

    Please report bugs in our authentication/permission system privately by submitting a vulnerability report.

    "},{"location":"Getting-Started/Configuration-File/","title":"Configuration File","text":"

    Below is a breakdown of each section of the config.yml file and its purpose. You can find a full example of the file in the config.example.yml file.

    "},{"location":"Getting-Started/Configuration-File/#exclude-section","title":"Exclude Section","text":"

    Control which platforms, ROMs, or files to ignore during scanning.

    "},{"location":"Getting-Started/Configuration-File/#platforms","title":"Platforms","text":"

    Exclude entire platforms (folders) from being scanned.

    exclude:\n    platforms: [\"ps\", \"ngc\", \"gba\"]\n
    "},{"location":"Getting-Started/Configuration-File/#roms","title":"ROMs","text":"

    Fine-tune which ROMs or files are excluded.

    "},{"location":"Getting-Started/Configuration-File/#single-file-roms","title":"Single File ROMs","text":"

    Applies to ROMs that are single files (not in subfolders).

    exclude:\n    roms:\n        single_file:\n            extensions: [\"xml\", \"txt\"]\n            names: [\"info.txt\", \"._*\", \"*.nfo\"]\n
    "},{"location":"Getting-Started/Configuration-File/#multi-file-roms","title":"Multi-File ROMs","text":"

    Applies to ROMs stored as folders (multi-disc, with DLC, etc.).

    exclude:\n    roms:\n        multi_file:\n            names: [\"final fantasy VII\", \"DLC\"]\n            parts:\n                names: [\"data.xml\", \"._*\"]\n                extensions: [\"xml\", \"txt\"]\n
    "},{"location":"Getting-Started/Configuration-File/#system-section","title":"System Section","text":"

    Customize how RomM interprets your folder and platform names.

    "},{"location":"Getting-Started/Configuration-File/#custom-folder-names","title":"Custom Folder Names","text":"

    Map your custom folder names to RomM's recognized platform names.

    system:\n    platforms:\n        gc: \"ngc\" # Treats 'gc' folder as GameCube\n        psx: \"ps\" # Treats 'psx' folder as PlayStation\n
    "},{"location":"Getting-Started/Configuration-File/#versions","title":"Versions","text":"

    Associate a platform with its main version. This also tells RomM to fetch metadata from the main version source.

    system:\n    versions:\n        naomi: \"arcade\"\n
    "},{"location":"Getting-Started/Configuration-File/#filesystem-section","title":"Filesystem Section","text":"

    Specify the folder name where your ROMs are located if it differs from the default.

    If your ROMs folder is named my_roms instead of roms:

    filesystem:\n    roms_folder: \"my_roms\"\n

    Disable file hash calculation for low power devices (e.g. Raspberry PI).

    filesystem:\n    skip_hash_calculation: true\n
    "},{"location":"Getting-Started/Configuration-File/#scan-section","title":"Scan Section","text":"

    Configure metadata scanning priorities and media assets to download.

    "},{"location":"Getting-Started/Configuration-File/#priority","title":"Priority","text":"

    Customize the order in which metadata providers are queried during scans.

    "},{"location":"Getting-Started/Configuration-File/#metadata","title":"Metadata","text":"

    Controls metadata provider priority order.

    Provider list in default order:

    scan:\n    priority:\n        metadata:\n            - \"igdb\"\n            - \"ss\"\n            - \"moby\"\n
    "},{"location":"Getting-Started/Configuration-File/#artwork","title":"Artwork","text":"

    Controls artwork provider priority order for cover art and screenshots.

    Default: Same as priority.metadata

    scan:\n    priority:\n        artwork:\n            - \"igdb\"\n            - \"ss\"\n            - \"moby\"\n
    "},{"location":"Getting-Started/Configuration-File/#region","title":"Region","text":"

    Sets preferred region for cover art and game title (Screenscraper only).

    Default: [\"us\", \"wor\", \"ss\", \"eu\", \"jp\"]

    scan:\n    priority:\n        region:\n            - \"us\"\n            - \"eu\"\n            - \"jp\"\n
    "},{"location":"Getting-Started/Configuration-File/#language","title":"Language","text":"

    Sets preferred language for cover art and game title (Screenscraper only).

    Default: [\"en\", \"fr\"]

    scan:\n    priority:\n        language:\n            - \"en\"\n            - \"es\"\n            - \"fr\"\n
    "},{"location":"Getting-Started/Configuration-File/#media","title":"Media","text":"

    Configures which media assets to download (Screenscraper and ES-DE gamelist.xml only).

    Media types:

    scan:\n    media:\n        - box2d\n        - screenshot\n        - manual\n        - bezel\n
    "},{"location":"Getting-Started/Configuration-File/#emulatorjs-section","title":"EmulatorJS Section","text":"

    Configure EmulatorJS per-core options and controls.

    "},{"location":"Getting-Started/Configuration-File/#debug","title":"Debug","text":"

    Enable debug mode to log available options to the browser console.

    emulatorjs:\n    debug: true\n
    "},{"location":"Getting-Started/Configuration-File/#cache-limit","title":"Cache Limit","text":"

    Cache limit per ROM in bytes. Set to null for unlimited.

    emulatorjs:\n    cache_limit: 52428800 # 50 MB\n
    "},{"location":"Getting-Started/Configuration-File/#disable-batch-bootup","title":"Disable batch bootup","text":"

    Skips the step that runs a batch file that sets soundcard information, mounts file systems, and attempts to run an autorun.bat file (try this if DOS games fail to boot).

    emulatorjs:\n    disable_batch_bootup: true\n
    "},{"location":"Getting-Started/Configuration-File/#disable-auto-unload","title":"Disable auto-unload","text":"

    The emulator stops/shuts itself down when you navigate to a new page; this setting stops that behaviour (if that's something you want).

    emulatorjs:\n    disable_auto_unload: true\n
    "},{"location":"Getting-Started/Configuration-File/#netplay","title":"Netplay","text":"

    Enable netplay and configure STUN/TURN servers. We recommend Google's public servers or Metered's free tier.

    emulatorjs:\n    netplay:\n        enabled: true\n        ice_servers:\n            - urls: \"stun:stun.l.google.com:19302\"\n            - urls: \"stun:stun1.l.google.com:19302\"\n            - urls: \"stun:stun2.l.google.com:19302\"\n            - urls: \"turn:openrelay.metered.ca:80\"\n              username: \"openrelayproject\"\n              credential: \"openrelayproject\"\n            - urls: \"turn:openrelay.metered.ca:443\"\n              username: \"openrelayproject\"\n              credential: \"openrelayproject\"\n
    "},{"location":"Getting-Started/Configuration-File/#settings","title":"Settings","text":"

    Configure core-specific settings. Use default to apply settings to all cores.

    emulatorjs:\n    settings:\n        parallel_n64: # Use the exact core name\n            vsync: disable\n        snes9x:\n            snes9x_region: ntsc\n        default: # These settings apply to all cores\n            fps: show\n
    "},{"location":"Getting-Started/Configuration-File/#controls","title":"Controls","text":"

    Map keyboard and controller controls for each player.

    Example (2-player SNES):

    emulatorjs:\n    controls:\n        snes9x:\n            0: # Player 1\n                0: # Button mapping\n                    value: x # Keyboard mapping\n                    value2: BUTTON_2 # Controller mapping\n            1: # Player 2\n                0:\n                    value: /\n                    value2: BUTTON_2\n

    See EmulatorJS documentation for control mapping details.

    Tip

    You can find examples of full binded batocera or es-de config files.

    Warning

    Only uncomment or add the lines you need. Any omitted or empty sections will use RomM's defaults.

    For a full example, see the config.example.yml file.

    "},{"location":"Getting-Started/Environment-Variables/","title":"Environment Variables","text":"

    This is a complete list of available environment variables; required variables are marked with a \u2713.

    Tip

    You can also set environment variables with a _FILE suffix, which will load the contents of the file specified in the variable into the variable without the suffix. For example, setting ROMM_AUTH_SECRET_KEY_FILE=/run/secrets/romm_auth_secret_key and creating a file with the secret key at the specified path will set ROMM_AUTH_SECRET_KEY to the contents of the file. Learn more.

    "},{"location":"Getting-Started/Environment-Variables/#application-settings","title":"Application settings","text":"Variable Description Required Default ROMM_AUTH_SECRET_KEY Generate a key with openssl rand -hex 32 \u2713 DISABLE_CSRF_PROTECTION Disables CSRF protection (not recommended) false DISABLE_DOWNLOAD_ENDPOINT_AUTH Disable auth on download endpoint (WebRcade, Tinfoil) false DISABLE_USERPASS_LOGIN Disables login with username and password (when using OIDC) false SESSION_MAX_AGE_SECONDS Maximum age of a session (in seconds) 1209600 (14 days) KIOSK_MODE Read-only mode for public displays or kiosks false UPLOAD_TIMEOUT Timeout for file uploads (in seconds) 600 (10 minutes) SCAN_TIMEOUT Timeout for the background scan/rescan tasks (in seconds) 14400 (4 hours) SCAN_WORKERS Number of worker processes for scanning tasks 1 TASK_TIMEOUT Timeout for the the rest of the background tasks (in seconds) 300 (5 minutes) TASK_RESULT_TTL How long to keep task results in Valkey (in seconds) 86400 (24 hours) SEVEN_ZIP_TIMEOUT Timeout for 7-Zip operations (in seconds) 60 DISABLE_EMULATOR_JS Disables playing in browser with EmulatorJS false DISABLE_RUFFLE_RS Disables playing flash games with RuffleRS false YOUTUBE_BASE_URL Base URL for alternate frontends (Piped, Invidious, etc.) https://www.youtube.com TZ Sets the timezone UTC ROMM_PORT Port on which the application listens 8080 ROMM_BASE_PATH Base folder path for library, resources and assets /romm ROMM_BASE_URL Base url for properly display container logs links (like register or recover password) 0.0.0.0 LOGLEVEL Logging level for the app INFO FORCE_COLOR Forces color output false NO_COLOR Disables color output false WEB_SERVER_CONCURRENCY Number of processes running the app 1 WEB_SERVER_KEEPALIVE Waiting time for requests on a Keep-Alive connection (in seconds) 2 WEB_SERVER_MAX_REQUESTS Maximum number of requests a worker will process before restarting 1000 WEB_SERVER_MAX_REQUESTS_JITTER Random jitter to add to the maximum number of requests a worker will process before restarting 100 WEB_SERVER_TIMEOUT Timeout for web server requests (in seconds) 300 WEB_SERVER_WORKER_CONNECTIONS Maximum number of simultaneous clients a single process can handle 1000"},{"location":"Getting-Started/Environment-Variables/#dependencies","title":"Dependencies","text":"Variable Description Required Default DB_HOST Host name of database instance \u2713 DB_PORT Port number of database instance 3306 DB_NAME Should match MYSQL_DATABASE in MariaDB romm DB_USER Database username (in MariaDB, should match MARIADB_USER) \u2713 DB_PASSWD Database password (in MariaDB, should match MARIADB_PASSWORD) \u2713 DB_QUERY_JSON Extra query parameters for the database connection, in JSON format (e.g. {\"unix_socket\": \"/path/to/db\"}) ROMM_DB_DRIVER Database driver to use (options: mariadb, mysql, postgresql) mariadb REDIS_HOST Host name of Redis/Valkey instance 127.0.0.1 REDIS_PORT Port number of Redis/Valkey instance 6379 REDIS_USERNAME Username for Redis/Valkey instance REDIS_PASSWORD Password for Redis/Valkey instance REDIS_DB Database number for Redis/Valkey instance 0 REDIS_SSL Enable SSL for Redis/Valkey instance false SENTRY_DSN DSN for Sentry error tracking"},{"location":"Getting-Started/Environment-Variables/#metadata-providers","title":"Metadata providers","text":"Variable Description Required Default IGDB_CLIENT_ID Client ID for IGDB API IGDB_CLIENT_SECRET Client secret for IGDB API SCREENSCRAPER_USER Screenscraper username SCREENSCRAPER_PASSWORD Screenscraper password MOBYGAMES_API_KEY MobyGames secret API key STEAMGRIDDB_API_KEY SteamGridDB secret API key RETROACHIEVEMENTS_API_KEY Retroachievements secret API key REFRESH_RETROACHIEVEMENTS_CACHE_DAYS Retroachievements metadata cache refresh (in days) 30 LAUNCHBOX_API_ENABLED Enable LaunchBox API integration false PLAYMATCH_API_ENABLED Enable PlayMatch API integration false HASHEOUS_API_ENABLED Enable Hasheous API integration false FLASHPOINT_API_ENABLED Enable Flashpoint API integration false HLTB_API_ENABLED Enable HowLongToBeat API integration false"},{"location":"Getting-Started/Environment-Variables/#authentication","title":"Authentication","text":"Variable Description Required Default OIDC_ENABLED Enable OpenID Connect (OIDC) authentication false OIDC_PROVIDER Name of the OIDC provider in use OIDC_CLIENT_ID Client ID for OIDC authentication OIDC_CLIENT_SECRET Client secret for OIDC authentication OIDC_REDIRECT_URI Absolute redirect URI for OIDC authentication OIDC_SERVER_APPLICATION_URL Absolute URL of the OIDC server application OIDC_TLS_CACERTFILE Path to a file containing trusted CA certificates OIDC_USERNAME_ATTRIBUTE Attribute on OIDC user info used as the username preferred_username"},{"location":"Getting-Started/Environment-Variables/#background-tasks","title":"Background tasks","text":"Variable Description Required Default ENABLE_RESCAN_ON_FILESYSTEM_CHANGE Enable re-scanning of library when filesystem changes false RESCAN_ON_FILESYSTEM_CHANGE_DELAY Delay before re-scanning library when filesystem changes (in minutes) 5 ENABLE_SCHEDULED_RESCAN Enable scheduled re-scanning of library false SCHEDULED_RESCAN_CRON Cron expression for scheduled re-scanning \"0 3 * * *\" ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB Enable scheduled updating of Switch TitleDB index false SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON Cron expression for scheduled updating of Switch TitleDB \"0 4 * * *\" ENABLE_SCHEDULED_UPDATE_LAUNCHBOX_METADATA Enable scheduled updating of LaunchBox metadata false SCHEDULED_UPDATE_LAUNCHBOX_METADATA_CRON Cron expression for scheduled updating of LaunchBox metadata \"0 4 * * *\" ENABLE_SCHEDULED_CONVERT_IMAGES_TO_WEBP Enable scheduled conversion of images to WebP format false SCHEDULED_CONVERT_IMAGES_TO_WEBP_CRON Cron expression for scheduled conversion of images to WebP format \"0 4 * * *\" ENABLE_SCHEDULED_RETROACHIEVEMENTS_PROGRESS_SYNC Enable scheduled syncing of Retroachievements progress false SCHEDULED_RETROACHIEVEMENTS_PROGRESS_SYNC_CRON Cron expression for scheduled syncing of Retroachievements progress \"0 4 * * *\""},{"location":"Getting-Started/Environment-Variables/#development","title":"Development","text":"Variable Description Required Default DEV_MODE Enable development mode (debugging, hot-reloading) false DEV_HOST Host for development server 127.0.0.1 DEV_PORT Port for development server 5000 DEV_SQL_ECHO Enable SQL query logging in development mode false"},{"location":"Getting-Started/Folder-Structure/","title":"Folder Structure","text":"

    RomM requires one of these folder structures for proper operation. It will first attempt to detect Structure A (recommended), and if not found, will fall back to Structure B. This auto-detection ensures flexibility while encouraging organization best practices.

    "},{"location":"Getting-Started/Folder-Structure/#folder-organization","title":"Folder Organization","text":"

    RomM organizes content in two main categories: ROMs and BIOS files.

    Note

    The BIOS folder is entirely optional and only needed for platforms that require BIOS files.

    When using Docker, the volume mount point differs based on your chosen structure:

    For multifile games (games stored as folders with multiple files or folders inside), RomM will detect special folders inside the game and will display with special tags in the webUI:

    Tip

    For folder naming conventions, review the Platform Support section. To override default system names in the folder structure (if your directories are named differently), see the Configuration File section.

    Structure A (recommended) Structure B (fallback) library/roms/{platform}/{game} library/{platform}/roms/{game}
    \n        library/\n        \u251c\u2500 roms/\n        \u2502  \u251c\u2500 gbc/\n        \u2502  \u2502  \u251c\u2500 game_1.gbc\n        \u2502  \u2502  \u2514\u2500 game_2.gbc\n        \u2502  \u2502\n        \u2502  \u251c\u2500 gba/\n        \u2502  \u2502  \u251c\u2500 game_3.gba\n        \u2502  \u2502  \u2514\u2500 game_4/\n        \u2502  \u2502     \u251c\u2500 game_4.gba\n        \u2502  \u2502     \u251c\u2500 dlc\n        \u2502  \u2502     \u2502  \u251c\u2500 game_4_dlc_1.7z\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_dlc_2.7z\n        \u2502  \u2502     \u251c\u2500 hack\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_hardmode.rar\n        \u2502  \u2502     \u251c\u2500 manual\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_manual.pdf\n        \u2502  \u2502     \u251c\u2500 mod\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_crazy_mode.zip\n        \u2502  \u2502     \u251c\u2500 patch\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_patch_v1.1.zip\n        \u2502  \u2502     \u251c\u2500 update\n        \u2502  \u2502     \u251c\u2500 demo\n        \u2502  \u2502     \u251c\u2500 translation\n        \u2502  \u2502     \u2514\u2500 prototype\n        \u2502  \u2502\n        \u2502  \u2514\u2500 ps/\n        \u2502     \u251c\u2500 game_5/\n        \u2502     \u2502   \u251c\u2500 game_5_cd_1.iso\n        \u2502     \u2502   \u2514\u2500 game_5_cd_2.iso\n        \u2502     \u2502\n        \u2502     \u2514\u2500 game_6.iso\n        \u2502\n        \u2514\u2500 bios/\n           \u251c\u2500 gba/\n           \u2502  \u2514\u2500 gba_bios.bin\n           \u2502\n           \u2514\u2500 ps/\n              \u251c\u2500 scph1001.bin\n              \u251c\u2500 scph5501.bin\n              \u2514\u2500 scph5502.bin\n      
    \n        library/\n        \u251c\u2500 gbc/\n        \u2502  \u2514\u2500 roms/\n        \u2502     \u251c\u2500 game_1.gbc\n        \u2502     \u2514\u2500 game_2.gbc\n        \u2502\n        \u251c\u2500 gba/\n        \u2502  \u251c\u2500 roms/\n        \u2502  \u2502  \u251c\u2500 game_3.gba\n        \u2502  \u2502  \u2514\u2500 game_4/\n        \u2502  \u2502     \u251c\u2500 game_4.gba\n        \u2502  \u2502     \u251c\u2500 dlc\n        \u2502  \u2502     \u2502  \u251c\u2500 game_4_dlc_1.7z\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_dlc_2.7z\n        \u2502  \u2502     \u251c\u2500 hack\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_hardmode.rar\n        \u2502  \u2502     \u251c\u2500 manual\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_manual.pdf\n        \u2502  \u2502     \u251c\u2500 mod\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_crazy_mode.zip\n        \u2502  \u2502     \u251c\u2500 patch\n        \u2502  \u2502     \u2502  \u2514\u2500 game_4_patch_v1.1.zip\n        \u2502  \u2502     \u251c\u2500 update\n        \u2502  \u2502     \u251c\u2500 demo\n        \u2502  \u2502     \u251c\u2500 translation\n        \u2502  \u2502     \u2514\u2500 prototype\n        \u2502  \u2502\n        \u2502  \u2514\u2500 bios/\n        \u2502     \u2514\u2500 gba_bios.bin\n        \u2502\n        \u2514\u2500 ps/\n           \u251c\u2500 roms/\n           \u2502  \u251c\u2500 game_5/\n           \u2502  \u2502  \u251c\u2500 game_5_cd_1.iso\n           \u2502  \u2502  \u2514\u2500 game_5_cd_2.iso\n           \u2502  \u2502\n           \u2502  \u2514\u2500 game_6.iso\n           \u2502\n           \u2514\u2500 bios/\n              \u251c\u2500 scph1001.bin\n              \u251c\u2500 scph5501.bin\n              \u2514\u2500 scph5502.bin\n      

    Note

    RomM can be setup without a prior folder structure. If files are manually uploaded from the webUI, RomM will automatically create the folder Structure A

    "},{"location":"Getting-Started/Folder-Structure/#configuration-file","title":"Configuration file","text":"

    RomM's behavior can be customized using a config.yml file or through the Library Management page in the Settings menu. You can grab the example config.example.yml file and adapt it to your library.

    What is shown in the Library Management page is the content of the config.yml. For more details read the configuration file section.

    "},{"location":"Getting-Started/Folder-Structure/#naming-convention","title":"Naming Convention","text":""},{"location":"Getting-Started/Folder-Structure/#tag-support","title":"Tag Support","text":"

    Games can be tagged with region, revision, or other tags by using parentheses in the file name. RomM will parse both tags with [] and ().

    Tags can be used to search for games in the search bar. For example, searching for (USA) will return all games with the USA tag.

    "},{"location":"Getting-Started/Folder-Structure/#supported-languages","title":"Supported Languages","text":"Code Language Ar Arabic Da Danish De German El Greek En English Es Spanish Fi Finnish Fr French It Italian Ja Japanese Ko Korean Nl Dutch No Norwegian Pl Polish Pt Portuguese Ru Russian Sr Serbian Sv Swedish Zh Chinese nolang No Language"},{"location":"Getting-Started/Folder-Structure/#supported-regions","title":"Supported Regions","text":"Code Region A Australia AS Asia B Brazil C Canada CH China E Europe F France FN Finland G Germany GR Greece H Holland HK Hong Kong I Italy J Japan K Korea NL Netherlands NO Norway PD Public Domain R Russia S Spain SW Sweden T Taiwan U USA UK England UNK Unknown UNL Unlicensed W World"},{"location":"Getting-Started/Metadata-Providers/","title":"Metadata Providers","text":"

    RomM supports multiple metadata providers to enrich your game library with titles, descriptions, cover art, and achievements. You don't need all providers, so this guide covers popular combos and setup instructions.

    "},{"location":"Getting-Started/Metadata-Providers/#popular-combos","title":"Popular combos","text":"

    Here are some combinations you can use based on your needs:

    "},{"location":"Getting-Started/Metadata-Providers/#the-french-connection-screenscraper-retroachievements","title":"\u2b50 The French Connection: ScreenScraper + Retroachievements","text":""},{"location":"Getting-Started/Metadata-Providers/#the-chefs-choice-hasheous-igdb-steamgriddb-retroachievements","title":"\u2b50 The Chef's Choice: Hasheous + IGDB + SteamGridDB + Retroachievements","text":""},{"location":"Getting-Started/Metadata-Providers/#the-twitch-fanboy-igdb-playmatch","title":"The Twitch Fanboy: IGDB + PlayMatch","text":""},{"location":"Getting-Started/Metadata-Providers/#the-quick-starter-hasheous","title":"The Quick Starter: Hasheous","text":""},{"location":"Getting-Started/Metadata-Providers/#setup-instructions","title":"Setup instructions","text":""},{"location":"Getting-Started/Metadata-Providers/#igdb","title":"IGDB","text":"

    IGDB (Internet Game Database) is a popular metadata provider that offers metadata, cover art, screenshots, related games and more.

    To access the IGDB API you'll need a Twitch account and a valid phone number for 2FA verification. Up-to-date instructions are available in the IGDB API documentation. When registering your application in the Twitch Developer Portal, fill out the form like so:

    Important

    The name you pick has to be unique! Picking an existing name will fail silently, with no error messages. We recommend using romm-<random hash>, like romm-3fca6fd7f94dea4a05d029f654c0c44b

    Note the client ID and secret that appear on screen, and use them to set IGDB_CLIENT_ID and IGDB_CLIENT_SECRET in your environment variables.

    Screenshots

    "},{"location":"Getting-Started/Metadata-Providers/#screenscraper","title":"ScreenScraper","text":"

    ScreenScraper.fr is a French provider that offers metadata, cover art, screenshots and manuals, along with the option for 3D boxes and CD/cartridge cover art. It supports a wide range of systems and is a great alternative to IGDB.

    To access the ScreenScraper API, create a ScreenScraper account and copy the user and password you just created to SCREENSCRAPER_USER and SCREENSCRAPER_PASSWORD respectively.

    "},{"location":"Getting-Started/Metadata-Providers/#mobygames","title":"MobyGames","text":"

    MobyGames is a metadata provider that offers metadata, cover art and screenshots.

    To access the MobyGames API, create a MobyGames account and then visit your profile page. Click the API link under your user name to sign up for an API key. Copy the key shown and use it to set MOBYGAMES_API_KEY.

    Important

    Access to the MobyGames API is a paid feature. While we will continue to support it, we recommend using ScreenScraper instead, as it is free to use.

    "},{"location":"Getting-Started/Metadata-Providers/#launchbox","title":"LaunchBox","text":"

    The LaunchBox Games Database is a community-driven database that provides metadata, cover art, and screenshots. Like the Launchbox desktop application, RomM downloads the entire database locally and matches games based on their exact filenames.

    To enable LaunchBox, set LAUNCHBOX_API_ENABLED=true in your environment variables. You can enable regular updates of the database by setting ENABLE_SCHEDULED_UPDATE_LAUNCHBOX_METADATA, and set the frequency on the cron job with SCHEDULED_UPDATE_LAUNCHBOX_METADATA_CRON (defaults to 5:00 AM every day).

    "},{"location":"Getting-Started/Metadata-Providers/#hasheous","title":"Hasheous","text":"

    Hasheous is a free, open-source metadata provider that uses file hashes to match games. It proxies IGDB data for titles, descriptions, and cover art, and can provide Retroachievements IDs for matched games.

    Simply set HASHEOUS_API_ENABLED=true in your environment variables, and future scans will start using the Hasheous API.

    "},{"location":"Getting-Started/Metadata-Providers/#playmatch","title":"PlayMatch","text":"

    PlayMatch is a hash-based matching service used in conjunction with IGDB to provide better matching for games, hosted by a member of our community.

    To enable PlayMatch, set PLAYMATCH_API_ENABLED=true in your environment variables.

    "},{"location":"Getting-Started/Metadata-Providers/#steamgriddb","title":"SteamGridDB","text":"

    SteamGridDB provides custom cover art for games or collections. It's not accessed through the scanner but from the \"search cover\" button when manually editing a game.

    To access the SteamGridDB API, you need to login to their website with a Steam account. Once logged in, go to your API tab under the preferences page. Copy the key shown and use it to set STEAMGRIDDB_API_KEY.

    "},{"location":"Getting-Started/Metadata-Providers/#retroachievements","title":"RetroAchievements","text":"

    RomM is able to display your achievements from RetroAchievements. To sync it with your RomM instance, you need to generate an API key from your RetroAchievements account in your settings.

    Copy the key shown and use it to set RETROACHIEVEMENTS_API_KEY and perform a UNMATCHED scan targeting the platform you want to match with RetroAchievements.

    After that, each user needs to set their own username in their profile and sync it with RetroAchievements. A new Achievements tab will appear in the Personal tab in the game details.

    To avoid unnecessary API calls, a cached file with the RA database is stored in RomM. Refresh time for that cache file can be changed with the environment variable REFRESH_RETROACHIEVEMENTS_CACHE_DAYS.

    Screenshots

    "},{"location":"Getting-Started/Metadata-Providers/#flashpoint","title":"Flashpoint","text":"

    The Flashpoint Project Database is a project that enables metadata for 180,000+ flash and browser-based games. Enable this metadata source with the FLASHPOINT_API_ENABLED=true environment variable. If you are adding this provider to an existing RomM setup, perform a UNMATCHED scan with Flashpoint selected to update an existing platform.

    "},{"location":"Getting-Started/Metadata-Providers/#how-long-to-beat","title":"How Long To Beat","text":"

    The How Long To Beat project provides game completion times for more than 84,000 games. Enable this metadata source with the HLTB_API_ENABLED=true environment variable. If you are adding this provider to an existing RomM setup, perform a UNMATCHED scan with How Long To Beat selected to update an existing platform.

    Game completion times will be added to a new tab on the details page for supported matched games.

    "},{"location":"Getting-Started/Metadata-Providers/#es-de-gamelistxml","title":"ES-DE gamelist.xml","text":"

    EmulationStation, and it's modern successor ES-DE, use a custom XML format to store game metadata. RomM can parse this format and import the assets as cover art and screenshots. You'll need to store the gamelist.xml file and any related assets under the platform folder:

    library/\n\u2514\u2500 roms/\n    \u2514\u2500 gba/\n        \u251c\u2500 game_1.gba\n        \u251c\u2500 game_2.gba\n        \u251c\u2500 gamelist.xml\n        \u251c\u2500 3dboxes/\n        \u2502  \u251c\u2500 game_1.png\n        \u2502  \u2514\u2500 game_2.png\n        \u251c\u2500 covers/\n        \u251c\u2500 screenshots/\n        \u2514\u2500 etc...\n
    "},{"location":"Getting-Started/Metadata-Providers/#es-de-settings","title":"ES-DE settings","text":"

    Here are the settings you need to change so RomM can read your artwork and gamelist.xml files from the same folder that holds your ROMs.

    1. Open the ES-DE settings file:

    2. Make these two edits (add the lines if they don\u2019t exist):

      <string name=\"MediaDirectory\" value=\"/path/to/ROMs/folder\" />\n<bool name=\"LegacyGamelistFileLocation\" value=\"true\" />\n
    3. If you already have scraped artwork, copy/move the systems from ~/ES-DE/downloaded_media/ and ~/ES-DE/gamelists/ into your ROMs folder

    After a restart, ES-DE will place new artwork and the updated gamelist.xml directly in roms/<system>/, which is the layout RomM expects.

    "},{"location":"Getting-Started/Metadata-Providers/#metadata-tags-in-filenames","title":"Metadata Tags in Filenames","text":"

    Scans will now parse custom metadata tags in the filename that match specific patterns, and use them to fetch game metadata for the specified ID. The supported tags are:

    (igdb-xxxx) for IGDB (moby-xxxx) for MobyGames (ra-xxxx) for RetroAchievements (ssfr-xxxx) for ScreenScraper (launchbox-xxxx) for Launchbox (hltb-xxxx) for HowLongToBeat

    Filenames will not be renamed by RomM to add tags, as they are a non-standard formatting system and could create conflicts with other software.

    "},{"location":"Getting-Started/OIDC-Setup/","title":"OIDC Setup","text":""},{"location":"Getting-Started/OIDC-Setup/#oidc-setup","title":"OIDC Setup","text":"

    OpenID Connect (OIDC) allows you to authenticate to RomM using external identity providers, enabling Single Sign-On (SSO) and centralized user management. This setup eliminates the need to manage separate credentials for RomM.

    "},{"location":"Getting-Started/OIDC-Setup/#what-is-oidc","title":"What is OIDC?","text":"

    OIDC is an identity layer built on top of OAuth2. While OAuth2 primarily handles authorization, OIDC adds authentication, enabling applications to verify a user's identity and obtain profile information. This makes OIDC suitable for SSO solutions, where user identity is central to access management.

    "},{"location":"Getting-Started/OIDC-Setup/#how-it-works","title":"How It Works","text":"
    1. Click the OIDC login button on RomM's login page
    2. You're redirected to your identity provider
    3. Authenticate with your credentials
    4. You're redirected back to RomM and logged in automatically
    "},{"location":"Getting-Started/OIDC-Setup/#supported-identity-providers","title":"Supported Identity Providers","text":"

    RomM supports OIDC authentication with the following identity providers:

    "},{"location":"Getting-Started/OIDC-Setup/#authelia","title":"Authelia","text":"

    An open-source authentication and authorization server providing two-factor authentication and SSO. Ideal for self-hosters looking for a lightweight solution.

    "},{"location":"Getting-Started/OIDC-Setup/#authentik","title":"Authentik","text":"

    An open-source identity provider with support for modern authentication protocols, MFA, and comprehensive user management.

    "},{"location":"Getting-Started/OIDC-Setup/#pocketid","title":"PocketID","text":"

    A simple OIDC provider that exclusively supports passkey authentication - no passwords required.

    "},{"location":"Getting-Started/OIDC-Setup/#zitadel","title":"Zitadel","text":"

    An enterprise-grade, open-source identity and access management platform supporting OAuth2, OIDC, SAML, and passwordless authentication.

    "},{"location":"Getting-Started/OIDC-Setup/#general-setup-requirements","title":"General Setup Requirements","text":"

    Regardless of which provider you choose, you'll need to configure these environment variables in RomM:

    OIDC_ENABLED=true\nOIDC_PROVIDER=<provider_name>\nOIDC_CLIENT_ID=<your_client_id>\nOIDC_CLIENT_SECRET=<your_client_secret>\nOIDC_REDIRECT_URI=<your_romm_url>/api/oauth/openid\nOIDC_SERVER_APPLICATION_URL=<your_provider_url>\n
    "},{"location":"Getting-Started/OIDC-Setup/#important-notes","title":"Important Notes","text":""},{"location":"Getting-Started/OIDC-Setup/#troubleshooting","title":"Troubleshooting","text":"

    If you encounter issues with OIDC authentication:

    "},{"location":"Getting-Started/OIDC-Setup/#next-steps","title":"Next Steps","text":"

    Choose a provider from the list above and follow its specific setup guide. Each guide provides detailed step-by-step instructions for configuring both the identity provider and RomM.

    "},{"location":"Getting-Started/Quick-Start-Guide/","title":"Quick Start Guide","text":"

    This quick start guide will help you get a RomM instance up and running. It is split into 3 parts: Prepare, Build and Configure.

    "},{"location":"Getting-Started/Quick-Start-Guide/#prepare","title":"Prepare","text":"

    There are a few things you need to have in place before you can start:

    Warning

    RomM works without a metadata API for basic use, but may cause issues with plugins like Playnite. Setting up IGDB API keys is recommended to prevent setup problems.

    "},{"location":"Getting-Started/Quick-Start-Guide/#build","title":"Build","text":"

    Now that we have everything gathered, we can begin getting your instance set up!

    1. Download a copy of the latest docker-compose.example.yml file from GitHub
    2. Edit the file and modify the following values to configure the database
    3. Modify the following values in the environment to configure the application. -- Other values can be changed, but should not be done unless you know what you are doing, and are outside the scope of this guide
    4. Run the following command in a terminal and save the output to the ROMM_AUTH_SECRET_KEY environment variable:
      openssl rand -hex 32\n
      It should look something like this:
      03a054b6ca27e0107c5eed552ea66becd9f3a2a8a91e7595cd462a593f9ecd09\n
    5. Add your metadata sources API keys:
    6. Modify the following values in the volumes to configure the application
    7. Save the file as docker-compose.yml instead of docker-compose.example.yml. It should look something like this:

      Example Docker Compose
      version: \"3\"\n\nvolumes:\n    mysql_data:\n    romm_resources:\n    romm_redis_data:\n\nservices:\n    romm:\n        image: rommapp/romm:latest\n        container_name: romm\n        restart: unless-stopped\n        environment:\n            - DB_HOST=romm-db\n            - DB_NAME=romm # Should match MARIADB_DATABASE in mariadb\n            - DB_USER=romm-user # Should match MARIADB_USER in mariadb\n            - DB_PASSWD= # Should match MARIADB_PASSWORD in mariadb\n            - ROMM_AUTH_SECRET_KEY= # Generate a key with `openssl rand -hex 32`\n            - SCREENSCRAPER_USER= # These are the recommended metadata providers\n            - SCREENSCRAPER_PASSWORD= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#screenscraper\n            - RETROACHIEVEMENTS_API_KEY= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#retroachievements\n            - STEAMGRIDDB_API_KEY= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#steamgriddb\n            - HASHEOUS_API_ENABLED=true # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#hasheous\n        volumes:\n            - romm_resources:/romm/resources # Resources fetched from IGDB (covers, screenshots, etc.)\n            - romm_redis_data:/redis-data # Cached data for background tasks\n            - /path/to/library:/romm/library # Your game library. Check https://github.com/rommapp/romm?tab=readme-ov-file#folder-structure for more details.\n            - /path/to/assets:/romm/assets # Uploaded saves, states, etc.\n            - /path/to/config:/romm/config # Path where config.yml is stored\n        ports:\n            - 80:8080\n        depends_on:\n            romm-db:\n                condition: service_healthy\n                restart: true\n\n    romm-db:\n        image: mariadb:latest\n        container_name: romm-db\n        restart: unless-stopped\n        environment:\n            - MARIADB_ROOT_PASSWORD= # Use a unique, secure password\n            - MARIADB_DATABASE=romm\n            - MARIADB_USER=romm-user\n            - MARIADB_PASSWORD=\n        volumes:\n            - mysql_data:/var/lib/mysql\n        healthcheck:\n            test: [CMD, healthcheck.sh, --connect, --innodb_initialized]\n            start_period: 30s\n            start_interval: 10s\n            interval: 10s\n            timeout: 5s\n            retries: 5\n
    8. Open the terminal and navigate to the directory containing the docker-compose file

    9. Run docker compose up -d to kick off the docker pull. You will see it pull the container and set up the volumes and network:

          {\n        \"file\": \"../latest/resources/asciinema/quick-start-docker-compose.cast\",\n        \"title\": \"RomM docker compose install\",\n        \"preload\": true,\n        \"loop\": true,\n        \"auto_play\": true,\n        \"cols\": 140,\n        \"rows\": 30,\n        \"fit\": \"width\",\n        \"terminal_font_size\": \"small\",\n        \"terminal_line_height\": \"1.2\",\n        \"terminal_font_family\": \"Roboto Mono, Monaco, Consolas, monospace\"\n    }\n
    10. Run docker ps -f name=romm to verify that the containers are running

    11. Open a web browser and navigate to http://localhost:80, where you should be greeted with the RomM setup page
    12. Go through the setup wizard, setting your admin username and password
    13. Log in with the credentials you set in the last step
    "},{"location":"Getting-Started/Quick-Start-Guide/#configure","title":"Configure","text":""},{"location":"Getting-Started/Quick-Start-Guide/#importing-your-roms-via-scanner","title":"Importing your ROMs via scanner","text":"

    This method is generally the fastest and recommended for first time setup. You need your library properly mounted as a container volume:

    1. Log into RomM with your user credentials
    2. Click the Scan button in the sidebar
    3. Select the metadata providers you want to fetch metadata from
    4. The system will now begin scanning the ROM files and applying metadata to them. You can click on any of the items that it has tagged to see the metadata it pulled without having to stop the scan
    5. After the scan completes, click the RomM logo to go back to the main screen. You should see the platforms and recent games it has scanned. You are now ready to rock with RomM!
    "},{"location":"Getting-Started/Quick-Start-Guide/#uploading-your-roms-via-web-interface","title":"Uploading your ROMs via Web Interface","text":"

    This method is certainly viable, but not recommended if you have a lot of ROMs and/or multiple platforms. It is good for adding files after the fact as your collection grows, but wouldn't be recommended for the first setup, nor for multi-file ROMs:

    1. Log into RomM with your user credentials
    2. Click the Upload button in the sidebar
    3. Select the platform, then click + ADD and select the ROMs you want to upload in the file selector that appears
    4. Click Upload to begin uploading the ROMs
    5. Repeat for all the roms/platforms you have

    "},{"location":"Getting-Started/Reverse-Proxy/","title":"Reverse Proxy","text":"

    Here are some basic configurations for popular reverse proxies. Additional configuration may be required depending on your specific setup.

    "},{"location":"Getting-Started/Reverse-Proxy/#caddy","title":"Caddy","text":"
    http://romm.mysite.com {\n  reverse_proxy romm:8080\n}\n
    "},{"location":"Getting-Started/Reverse-Proxy/#caddy-tls-https","title":"Caddy + TLS (HTTPS)","text":"
    https://romm.mysite.com {\n  tls mysite.com.crt mysite.com.key  # Certificate and key files\n\n  encode zstd gzip\n\n  header * {\n    Strict-Transport-Security \"max-age=31536000;\"\n    X-XSS-Protection \"1; mode=block\"\n    X-Frame-Options \"SAMEORIGIN\"\n    X-Robots-Tag \"noindex, nofollow\"\n    -Server\n    -X-Powered-By\n  }\n\n  reverse_proxy romm:8080\n}\n
    "},{"location":"Getting-Started/Reverse-Proxy/#nginx","title":"Nginx","text":"
    server {\n  listen 80 default_server;\n  server_name romm.mysite.com;\n  client_max_body_size 0;\n\n  location / {\n    include /config/nginx/proxy.conf;\n    include /config/nginx/resolver.conf;\n    set $upstream_app romm;\n    set $upstream_port 8080;\n    set $upstream_proto http;\n    proxy_pass $upstream_proto://$upstream_app:$upstream_port;\n  }\n}\n
    "},{"location":"Getting-Started/Reverse-Proxy/#nginx-tls-https","title":"Nginx + TLS (HTTPS)","text":"
    server {\n  listen 80 default_server;\n  server_name _;\n  return 301 https://$host$request_uri;\n}\n\nserver {\n    listen 443 ssl http2;\n    listen [::]:443 ssl http2;\n\n    server_name romm.mysite.com;\n    include /config/nginx/ssl.conf;\n    client_max_body_size 0;\n\n    location / {\n      include /config/nginx/proxy.conf;\n      include /config/nginx/resolver.conf;\n      set $upstream_app romm;\n      set $upstream_port 8080;\n      set $upstream_proto http;\n      proxy_pass $upstream_proto://$upstream_app:$upstream_port;\n\n      # Hide version\n      server_tokens off;\n\n      # Security headers\n      add_header X-Frame-Options \"SAMEORIGIN\" always;\n      add_header X-Content-Type-Options \"nosniff\" always;\n      add_header X-XSS-Protection \"1; mode=block\" always;\n      add_header Strict-Transport-Security \"max-age=31536000; includeSubDomains\" always;\n      add_header Referrer-Policy \"no-referrer-when-downgrade\" always;\n    }\n}\n
    "},{"location":"Getting-Started/Reverse-Proxy/#nginx-proxy-manager","title":"Nginx Proxy Manager","text":"

    Items marked with \u2757 are important to set, as RomM may not work correctly otherwise!

    "},{"location":"Getting-Started/Reverse-Proxy/#details","title":"\u26a1 Details","text":""},{"location":"Getting-Started/Reverse-Proxy/#ssl","title":"\ud83d\udee1\ufe0f SSL","text":"

    Strongly recommended for security; enable this if you plan to use HTTPS.

    "},{"location":"Getting-Started/Reverse-Proxy/#advanced","title":"\u2699\ufe0f Advanced","text":"

    Custom Nginx Configuration \u2757

    proxy_max_temp_file_size 0;\n
    Details SSL Advanced"},{"location":"Getting-Started/Reverse-Proxy/#traefik","title":"Traefik","text":""},{"location":"Getting-Started/Reverse-Proxy/#using-a-configuration-document","title":"Using a configuration document","text":"
    http:\n    romsdomainse:\n        entryPoints:\n            - \"https\"\n        rule: \"Host(`roms.domain.se`)\"\n        middlewares:\n            - default-headers\n            - https-redirectscheme\n        tls:\n            certResolver: http\n        service: romsdomainse\n\nservices:\n    romsdomainse:\n        loadBalancer:\n            servers:\n                - url: \"http://192.168.1.100:8080\"\n            passHostHeader: true\n
    "},{"location":"Getting-Started/Reverse-Proxy/#using-labels-in-docker-compose","title":"Using labels in docker compose","text":"
    labels:\n    - \"traefik.enable=true\"\n    - \"traefik.http.services.romm.loadbalancer.server.port=8080\"\n    - \"traefik.http.routers.romm.rule=Host(`romm.YOUR_DOMAIN.com`)\"\n    - \"traefik.http.routers.romm.entrypoints=websecure\"\n    - \"traefik.http.routers.romm.tls=true\"\n    - \"traefik.http.routers.romm.tls.certresolver=https\"\n
    "},{"location":"Integrations/Playnite-plugin/","title":"Playnite plugin","text":"

    Playnite is an open source video game library manager with one simple goal: To provide a unified interface for all of your games.

    This plugin allows you to import your RomM library into Playnite. It queries the RomM API to create Playnite library entires for each of your games. Installing a game in Playnite will download it from RomM and store it on your system, allowing you to launch it in your emulator of choice.

    "},{"location":"Integrations/Playnite-plugin/#installation","title":"Installation","text":""},{"location":"Integrations/Playnite-plugin/#setup","title":"Setup","text":""},{"location":"Integrations/Playnite-plugin/#emulators","title":"Emulators","text":"

    The plugin requires that you have at least 1 emulator installed on your system and configured in Playnite. You can use a built-in emulator or a custom one. If no emulators are installed and configured, you won't be able to complete setup! To set up an emulator, go to Menu -> Library -> Configure Emulators... -> Add emulator....

    "},{"location":"Integrations/Playnite-plugin/#settings","title":"Settings","text":"

    The plugin needs to be configured before it can be used. To do this, go to Menu -> Library -> Configure Integrations... -> RomM.

    "},{"location":"Integrations/Playnite-plugin/#authentication","title":"Authentication","text":"

    You'll need to enter the host URL of your RomM instance, as well as a username and password. Passwords are stored in plaintext in Playnite, so it's recommended to use a separate account with the \"VIEWER\" role. The host URL has the include the protocol (http/https) and should not include a trailing slash, e.g. https://romm.example.com.

    "},{"location":"Integrations/Playnite-plugin/#emulator-path-mappings","title":"Emulator path mappings","text":"Field Description Example Required Emulator A built-in (or custom) emulator Dolphin \u2713 Emulator Profile A built-in (or custom) emulator profile Nintendo GameCube \u2713 Platform The platform or console Nintendo GameCube \u2713 Destination Path The path where downloaded ROMs will be stored C:\\roms\\gc \u2713 Auto-extract Whether compressed files should be extracted automatically Enabled Whether the mapping is enabled"},{"location":"Integrations/Playnite-plugin/#importing-your-library","title":"Importing your library","text":"

    Once you've set up the plugin, you can import your library by going to Menu -> Library -> Import RomM library. All games matching the emulator path mappings will be imported into Playnite.

    Installing a game will download it from RomM and store it in the destination path. You can then launch the game from Playnite, and it will be launched using the configured emulator.

    By default, compressed files will be extracted automatically into a folder matching the game's name. You can modify this behavior in the settings page.

    "},{"location":"Integrations/Tinfoil-integration/","title":"Tinfoil Integration","text":"

    Tinfoil is a homebrew application for the Nintendo Switch, primarily used for installing and managing software, including games and updates, that are not obtained through official channels.

    This will help you configure Tinfoil for your Switch to work with your RomM library.

    "},{"location":"Integrations/Tinfoil-integration/#setup","title":"Setup","text":""},{"location":"Integrations/Tinfoil-integration/#prepare","title":"Prepare","text":"

    Please note down the following in order to make this as smooth as possible, as well as some pre-reqs:

    "},{"location":"Integrations/Tinfoil-integration/#configure","title":"Configure","text":"

    Now it's time to configure your switch - Please follow the steps, this will assume you have Tinfoil installed and know how to use the basic functions of it.

    1. Open Tinfoil and go to File Browser
    2. Scroll over to the selection and press - in order to access the new menu.
    3. Enter these Options
    4. Press X to save
    5. Now close out of Tinfoil and go back in, so it can scan the TitleIDs - if everything is correct you will have this custom motd: \" RomM Switch Library\"

    Now you will be able to see the files in \"New Games\" tab of Tinfoil OR you can access it within the \"File Browser\" section that you setup earlier.

    "},{"location":"Integrations/Tinfoil-integration/#additional","title":"Additional","text":"

    It didn't pull anything through to \"New Games\" and has not parsed any information about the titles?!

    That would be because the filename it has tried to pull had no TitleID (Improvement to RomM coming soon )

    Make sure the filename has the TitleID within the title like this:

    Once this is done, the next time Tinfoil is opened it is always parsed and re-scanned.

    "},{"location":"Integrations/muOS-app/","title":"muOS app","text":"

    muOS is a Custom Firmware (CFW) primarily for handheld devices. Configurable, themeable, friendly, easy-to-use.

    The muOS app connects to your RomM instance and allows you to fetch games wirelessly from your Anbernic device.

    "},{"location":"Integrations/muOS-app/#setup","title":"Setup","text":""},{"location":"Integrations/muOS-app/#muos","title":"muOS","text":"

    We leverage the muOS Archive Manager to install/update the app.

    1. Head to the latest release and download the RomM.muOS.x.x.x.muxapp file.
    2. Move the muxapp file to /mnt/mmc/ARCHIVE on your device.
    3. Launch the manager from Applications > Archive Manager and select RomM.muOS.x.x.x.muxapp.
    4. Once installed, make a copy of /mnt/mmc/MUOS/application/RomM/env.template, rename it to /mnt/mmc/MUOS/application/RomM/.env, edit it (any method is fine, we recommend SSH) and set HOST, USERNAME and PASSWORD.
    5. Launch the app from Applications > RomM and start browsing your collection.
    "},{"location":"Integrations/muOS-app/#emulationstation","title":"EmulationStation","text":"

    We use PortMaster to install the app on devices running EmulationStation.

    1. Download the RomM App.sh file and RomM/ folder to the roms/ports on your device.
    2. Make the RomM App.sh file executable by running chmod +x RomM App.sh.
    3. Launch EmulationStation and navigate to the Ports section.

    Note

    Your device must connect to your RomM instance or home server over Wi-Fi. The easiest method is to keep them on the same network and set HOST to the server's IP and the port where RomM is running. Advanced users or those using reverse proxies can configure their network and DNS settings as needed, using a URL with a domain like https://romm.domain.com.

    "},{"location":"Maintenance/Migrating-to-new-machine/","title":"Migrating RomM","text":""},{"location":"Maintenance/Migrating-to-new-machine/#migrating-romm-to-a-new-system","title":"Migrating RomM to a new system","text":"

    Migrating RomM to a new system is possible, but all of the docker volumes must be copied for RomM to run correctly.

    Following the the setup in the Quick Start Guide these volumes are created be default

    RomM should be stopped before following this guide.

    volumes:\n    mysql_data:\n    romm_resources:\n    romm_redis_data:\n\nservices:\n    romm:\n        volumes:\n            - romm_resources\n            - romm_redis_data\n    romm-db:\n        volumes:\n            - mysql_data\n

    These volumes will need to manually moved to the new system. This is a straightforward process that includes determining their location and then copying them.

    "},{"location":"Maintenance/Migrating-to-new-machine/#determining-the-docker-root-directory-and-copying-the-volumes","title":"Determining the docker root directory and copying the volumes","text":"
    1. First determine the docker root directory
    docker info | grep 'Docker Root Dir'\n

    The expected output on a standard linux system:

    Docker Root Dir: /var/lib/docker\n
    1. Double check that the volumes have been created by docker and are owned by the docker engine
    docker volume ls\n

    Following the default quick start guide the following volumes will have been made

    DRIVER    VOLUME NAME\nlocal     romm_mysql_data\nlocal     romm_romm_redis_data\nlocal     romm_romm_resources\n
    1. Inspect each volume to get the exact location of the volume data
    docker volume inspect romm_mysql_data | grep Mountpoint\n
    \"Mountpoint\": \"/var/lib/docker/volumes/romm_mysql_data/_data\",\n
    1. Copy those volumes into a new location so that they can be safely migrated to a new system each volume needs to be in its own folder
    cp -r /var/lib/docker/volumes/romm_mysql_data/_data/ /your/new/path/romm_mysql_data\n\ncp -r /var/lib/docker/volumes/romm_romm_redis_data/_data /your/new/path/romm_romm_redis_data\n\ncp -r /var/lib/docker/volumes/romm_romm_resources/_data /your/new/path/romm_romm_resources\n
    1. Update the docker-compose.yml volume paths with the newly copied data to determine RomM still loads correctly.
    services:\n    romm:\n        volumes:\n            - /your/new/path/romm_romm_resources # romm_resources\n            - /your/new/path/romm_romm_redis_data # romm_redis_data\n    romm-db:\n        volumes:\n            - /your/new/path/romm_mysql_data # mysql_data\n

    If RomM starts up correctly, then it is safe to copy all of your RomM folders to a new system.

    "},{"location":"Maintenance/Scheduled-Tasks/","title":"Scheduled Tasks","text":""},{"location":"Maintenance/Scheduled-Tasks/#scheduled-tasks","title":"Scheduled tasks","text":"

    Scheduled tasks can be enabled and configured with the following environment variables:

    Variable Description Value ENABLE_SCHEDULED_RESCAN Enable scheduled re-scanning of library true SCHEDULED_RESCAN_CRON Cron expression for scheduled re-scanning \"0 3 * * *\" ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB Enable scheduled updating of Switch TitleDB index true SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON Cron expression for scheduled updating of Switch TitleDB \"0 4 * * *\" ENABLE_SCHEDULED_UPDATE_LAUNCHBOX_METADATA Enable scheduled updating of LaunchBox metadata true SCHEDULED_UPDATE_LAUNCHBOX_METADATA_CRON. Cron expression for scheduled updating of LaunchBox metadata \"0 5 * * *\""},{"location":"Maintenance/Scheduled-Tasks/#scheduled-re-scan","title":"Scheduled re-scan","text":"

    Users can opt to enable scheduled re-scans, and set the interval using Cron notation. Not that the scan will not completely re-scan every file, only catching those which have been added/updated.

    "},{"location":"Maintenance/Scheduled-Tasks/#switch-titledb-update","title":"Switch titleDB update","text":"

    Support was added for Nintendo Switch ROMs with filenames using the titleid/programid format (e.g. 0100000000010000.xci). If a file under the switch folder matches the regex, the scanner will use the index to attempt to match it to a game. If a match is found, the IGDB handler will use the matched name as the search term.

    The associated task updates the /fixtures/switch_titledb.json file at a regular interval to support new game releases.

    "},{"location":"Maintenance/Scheduled-Tasks/#launchbox-metadata-update","title":"LaunchBox metadata update","text":"

    RomM can also update the LaunchBox metadata database at a regular interval. This is onyl useful if you've enabled the LaunchBox metadata provider. The database is updated by downloading the latest version from the LaunchBox Games Database and replacing the existing one.

    "},{"location":"Maintenance/Scheduled-Tasks/#file-system-watcher","title":"File system watcher","text":"

    RomM can also monitor the filesystem for events (files created/moved/deleted) and schedules a re-scan of the platform (or entire library is a new platform was added).

    The watcher can be enabled and configured with the following environment variables:

    Variable Description Value ENABLE_RESCAN_ON_FILESYSTEM_CHANGE Enable re-scanning of library when filesystem changes true RESCAN_ON_FILESYSTEM_CHANGE_DELAY Delay in minutes before re-scanning library when filesystem changes 5

    The watcher will monitor the /library/roms folder for changes to the filesystem, such as files being added, moved or deleted. It will ignore certain events (like modifying the file content or metadata), and will skip default OS files (like .DS_Store on mac).

    When a change is detected, a scan will be scheduled for sometime in the future (default 5 minutes). If other events are triggered between now and the time at which the scan starts, more platforms will be added to the scan list (or the scan may switch to a full scan). This is done to reduce the number of tasks scheduled when many big changes happen to the library (mass upload, new mount, etc.)

    "},{"location":"Maintenance/Upgrading-to-3.0/","title":"Upgrading to 3.0","text":"

    Version 3.0 of RomM introduces a number of breaking changes aimed at improving performance and usability, which will require some users to make specific changes before upgrading to ensure compatibility and to take full advantage of the new features.

    All of the following changes are reflected in the example docker-compose.yml file, which has been simplified greatly. Please read this entire file carefully, as failing to do so may cause RomM to become inaccessible or unresponsive.

    "},{"location":"Maintenance/Upgrading-to-3.0/#dropped-support-for-sqlite","title":"Dropped support for SQLite","text":"

    We're removed support for SQLite as we've faced a number of engineering issues with it in the past, and MariaDB has proven more stable and robust. If you currently use SQLite, we'll automatically migrate your data from SQLite to MariaDB, but you'll first need to make the following changes before upgrading to the latest image.

    In your environment variables, change ROMM_DB_DRIVER to mariadb (or remove it completely as it's no longer needed). You'll then want to add the following environment variables:

    - DB_HOST=mariadb\n- DB_PORT=3306\n- DB_NAME=romm # Should match MYSQL_DATABASE in mariadb\n- DB_USER=romm-user # Should match MYSQL_USER in mariadb\n- DB_PASSWD= # Should match MYSQL_PASSWORD in mariadb\n

    To setup a new MariaDB container, have a look at the example docker-compose.yml file.

    "},{"location":"Maintenance/Upgrading-to-3.0/#authentication-as-standard","title":"Authentication as standard","text":"

    To support new features like EmulatorJS and saves/states management, we've decided to require authentication for all users. Anyone currently running RomM with authentication disabled will need to remove the ROMM_AUTH_ENABLED environment variable and add the following ones:

    - ROMM_AUTH_SECRET_KEY= # Generate a key with `openssl rand -hex 32`\n

    We understand that this requirement for authentication might conflict with the way some users currently share their collection with others (unrestricted access for all). However, given the exciting new features we've built, and the ones we're looking to build in the near future, we feel this is the right decision for the project.

    "},{"location":"Maintenance/Upgrading-to-3.0/#redis-is-now-built-in","title":"Redis is now built-in","text":"

    As Redis is required for authentication to work, we've integrated it directly into the docker image. If you're currently running the experimental Redis container, you can remove it, along with these environment variables:

    - ENABLE_EXPERIMENTAL_REDIS\n- REDIS_HOST\n- REDIS_PORT\n
    "},{"location":"Maintenance/Upgrading-to-3.0/#configuration-folder","title":"Configuration folder","text":"

    Mounting the config.yml file is now done by mounting a config folder.. Place your existing config.yml file inside a folder and bind it to /romm/config:

    - /path/to/config:/romm/config\n

    Updated config.example.yml

    "},{"location":"Maintenance/Upgrading-to-3.0/#support-for-saves-states-and-screenshots","title":"Support for saves, states and screenshots","text":"

    This version introduces preliminary support for uploading/downloading saves, states and screenshots (read more about it in the 3.0 release notes). We've added a new volume mapping for these types of files called assets, which you'll want to bind to a local folder (or volume) so they'll persist. In your volumes section, add the following mapping, where /path/to/assets/ is some folder where you'll want to store these assets (and make sure that folder exists):

    - /path/to/assets:/romm/assets\n

    We recommend creating a folder next to your library/the one mapped to /romm/library in order to keep all your RomM files in the same place.

    "},{"location":"Miscellaneous/Brand-Guidelines/","title":"Branding Guidelines","text":"

    We\u2019ve put together some guidelines for those anyone who wants to use our name and logo. In this context, \"RomM\", \"The RomM Project\", \"the project\", \"we\", \"us\", and \"our\" refer to the RomM project.

    "},{"location":"Miscellaneous/Brand-Guidelines/#the-logo","title":"The Logo","text":"The logo should always be used in its standard colors: Color Hex Code #371f69 #553e98 #ede5f8 #bea4e1 #e6c7a7 #e1a38d"},{"location":"Miscellaneous/Brand-Guidelines/#do-these-things","title":"Do these things","text":"

    If you're working on a project that integrates with RomM and would like to use/remix the logo, please reach out to us first. We'd love to hear about what you're working on!

    "},{"location":"Miscellaneous/Brand-Guidelines/#please-dont-do-these-things","title":"Please don't do these things","text":""},{"location":"Miscellaneous/FAQs/","title":"FAQs","text":""},{"location":"Miscellaneous/FAQs/#when-will-the-next-version-of-romm-be-available","title":"When will the next version of RomM be available?","text":"

    When it's ready.

    "},{"location":"Miscellaneous/FAQs/#when-will-the-version-after-that-one-release","title":"When will the version after that one release?","text":"

    After the upcoming version is released.

    "},{"location":"Miscellaneous/FAQs/#when-will-x-feature-be-available","title":"When will X feature be available?","text":"

    Sometime between now and the heat death of the universe.

    "},{"location":"Miscellaneous/FAQs/#when-will-version-xxx-of-romm-or-any-of-the-romm-clientsappsplugins-be-released","title":"When will version x.x.x of RomM (or any of the RomM clients/apps/plugins) be released?","text":"

    Same as above question.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/","title":"With Authelia","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#oidc-setup-with-authelia","title":"OIDC Setup With Authelia","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#a-quick-rundown-of-the-technologies","title":"A quick rundown of the technologies","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#what-is-authelia","title":"What is Authelia?","text":"

    Authelia is an open-source authentication and authorization server providing two-factor authentication and single sign-on (SSO) for your applications via a web portal. It acts as a companion for reverse proxies by allowing, denying, or redirecting requests. Authelia can be deployed alongside your other services to centralize identity management.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#what-is-oauth2","title":"What is OAuth2?","text":"

    OAuth2 (Open Authorization 2.0) is an industry-standard protocol for authorization. It allows applications (clients) to gain limited access to user accounts on an HTTP service without sharing the user\u2019s credentials. Instead, it uses access tokens to facilitate secure interactions. OAuth2 is commonly used in scenarios where users need to authenticate via a third-party service.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#what-is-openid-connect-oidc","title":"What is OpenID Connect (OIDC)?","text":"

    OIDC (OpenID Connect) is an identity layer built on top of OAuth2. While OAuth2 primarily handles authorization, OIDC adds authentication, enabling applications to verify a user\u2019s identity and obtain profile information. This makes OIDC suitable for SSO solutions, where user identity is central to access management.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#setting-up-a-provider-and-application-in-authelia","title":"Setting up a Provider and Application in Authelia","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#step-1-install-and-configure-authelia","title":"Step 1: Install and Configure Authelia","text":"

    Before setting up a provider and app, ensure that Authelia is installed and running by following the getting started and OIDC provider guides.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#step-2-add-a-client","title":"Step 2: Add a client","text":"

    First, in Authelia's configuration.yml, at identity_providers \u2192 oidc \u2192 claims_policies you'll need to add a Claims Policy if you do not already have one with the specified claims:

    # identity_providers:\n#   oidc:\nclaims_policies:\n    with_email: # You can name this however you want\n        id_token:\n            [\n                \"email\",\n                \"email_verified\",\n                \"alt_emails\",\n                \"preferred_username\",\n                \"name\",\n            ]\n

    To read more about claims_policies and why you need it for RomM, see this section in the Authelia docs.

    Then, in the same configuration.yml, under identity_providers \u2192 oidc \u2192 clients, add a new entry:

    Refer to the official docs for more details.

    This entry should look like this:

    #identity_providers:\n#  oidc:\n#    clients:\n- client_id: \"<randomly_generated>\" # read above for how generate\n  client_name: \"RomM\" # will be displayed in Authelia to users\n  client_secret: \"$pbkdf2-sha512$randomly_generated\" # read above for how generate\n  public: false\n  authorization_policy: \"two_factor\" # or one_factor, depending on your needs\n  grant_types:\n      - authorization_code\n  redirect_uris:\n      - \"http://romm.host.local/api/oauth/openid\"\n  claims_policy: \"with_email\"\n  scopes:\n      - \"openid\"\n      - \"email\"\n      - \"profile\"\n  userinfo_signed_response_alg: \"none\"\n  token_endpoint_auth_method: \"client_secret_basic\"\n
    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#step-3-configure-romm-environment-variables","title":"Step 3: Configure RomM Environment Variables","text":"

    To enable OIDC authentication in RomM, you need to set the following environment variables:

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#step-4-set-your-email-in-romm","title":"Step 4: Set your Email in RomM","text":"

    In RomM, open your user profile and set your email address. This email has to match your user email in Authelia.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authelia/#step-5-test-the-integration","title":"Step 5: Test the Integration","text":"

    After configuring the environment variables, restart (or stop and remove) your RomM instance and navigate to the login page. You should see an option to log in using OIDC. Click on the OIDC button, and you'll be redirected to Authelia for authentication. Once authenticated, you'll be redirected back to RomM.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/","title":"With Authentik","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#oidc-setup-with-authentik","title":"OIDC Setup With Authentik","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#a-quick-rundown-of-the-technologies","title":"A quick rundown of the technologies","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#what-is-authentik","title":"What is Authentik?","text":"

    Authentik is an open-source identity provider (IdP) designed to manage authentication, authorization, and user management across applications. It supports modern authentication protocols and provides tools to simplify integration, including single sign-on (SSO), multi-factor authentication (MFA), and auditing capabilities. Authentik can be deployed alongside your other services to centralize identity management.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#what-is-oauth2","title":"What is OAuth2?","text":"

    OAuth2 (Open Authorization 2.0) is an industry-standard protocol for authorization. It allows applications (clients) to gain limited access to user accounts on an HTTP service without sharing the user\u2019s credentials. Instead, it uses access tokens to facilitate secure interactions. OAuth2 is commonly used in scenarios where users need to authenticate via a third-party service.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#what-is-openid-connect-oidc","title":"What is OpenID Connect (OIDC)?","text":"

    OIDC (OpenID Connect) is an identity layer built on top of OAuth2. While OAuth2 primarily handles authorization, OIDC adds authentication, enabling applications to verify a user\u2019s identity and obtain profile information. This makes OIDC suitable for SSO solutions, where user identity is central to access management.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#setting-up-a-provider-and-application-in-authentik","title":"Setting up a Provider and Application in Authentik","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#step-1-install-and-configure-authentik","title":"Step 1: Install and Configure Authentik","text":"

    Before setting up a provider and app, ensure that Authentik is installed and running by following the official installation guide..

    1. Access Authentik via its web interface.
    2. Log in as an administrator.
    3. Navigate to the \u201cAdmin Interface\u201d to configure the necessary components.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#step-2-create-a-provider","title":"Step 2: Create a Provider","text":"

    A provider in Authentik acts as the bridge between RomM and Authentik.

    1. Navigate to Providers:
    2. Create a New Provider:
    3. Select \"OAuth2/OpenID Provider\"
    4. Configure Provider Settings:
    5. Copy the Client ID and Secret:
    6. Click Create.
    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#step-3-register-an-application","title":"Step 3: Register an Application","text":"

    An app in Authentik represents the external service (in our case RomM) that will use the provider for authentication.

    1. Navigate to Applications:
    2. Create a New Application:
    3. Click Create.
    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#step-4-configure-romm-environment-variables","title":"Step 4: Configure RomM Environment Variables","text":"

    To enable OIDC authentication in RomM, you need to set the following environment variables:

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#step-5-set-your-email-in-romm","title":"Step 5: Set your Email in RomM","text":"

    In RomM, open your user profile and set your email address. This email has to match your user email in Authentik.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Authentik/#step-6-test-the-integration","title":"Step 6: Test the Integration","text":"

    After configuring the environment variables, restart (or stop and remove) your RomM instance and navigate to the login page. You should see an option to log in using OIDC. Click on the OIDC button, and you'll be redirected to Authentik for authentication. Once authenticated, you'll be redirected back to RomM.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/","title":"With PocketID","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#oidc-setup-with-pocket-id","title":"OIDC Setup With Pocket ID","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#a-quick-rundown-of-the-technologies","title":"A quick rundown of the technologies","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#what-is-pocket-id","title":"What is Pocket ID?","text":"

    Pocket ID is a simple OIDC provider that allows users to authenticate with their passkeys to your services.

    The goal of Pocket ID is to be a simple and easy-to-use. There are other self-hosted OIDC providers like Keycloak or ORY Hydra but they are often too complex for simple use cases.

    Additionally, what makes Pocket ID special is that it only supports passkey authentication, which means you don\u2019t need a password.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#what-is-oauth2","title":"What is OAuth2?","text":"

    OAuth2 (Open Authorization 2.0) is an industry-standard protocol for authorization. It allows applications (clients) to gain limited access to user accounts on an HTTP service without sharing the user\u2019s credentials. Instead, it uses access tokens to facilitate secure interactions. OAuth2 is commonly used in scenarios where users need to authenticate via a third-party service.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#what-is-openid-connect-oidc","title":"What is OpenID Connect (OIDC)?","text":"

    OIDC (OpenID Connect) is an identity layer built on top of OAuth2. While OAuth2 primarily handles authorization, OIDC adds authentication, enabling applications to verify a user\u2019s identity and obtain profile information. This makes OIDC suitable for SSO solutions, where user identity is central to access management.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#setting-up-a-client-in-pocket-id","title":"Setting up a client in Pocket ID","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#step-1-install-and-configure-pocket-id","title":"Step 1: Install and Configure Pocket ID","text":"

    Before setting up the OIDC client, ensure that Pocket ID is installed and running by following the setup guide.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#step-2-add-a-client","title":"Step 2: Add a client","text":"

    Once you have logged in and configured a PassKey you now need to create an OIDC client, this will let Pocket ID know about the application that needs to be configured, and will give you the relevant keys to add to the RomM compose file.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#step-3-configure-romm-environment-variables","title":"Step 3: Configure RomM Environment Variables","text":"

    To enable OIDC authentication in RomM, you need to set the following environment variables:

    "},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#step-4-set-your-email-in-romm","title":"Step 4: Set your Email in RomM","text":"

    In RomM, open your user profile and set your email address. This email has to match your user email in Pocket ID.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-PocketID/#step-5-test-the-integration","title":"Step 5: Test the Integration","text":"

    After configuring the environment variables, restart (or stop and remove) your RomM instance and navigate to the login page. You should see an option to log in using OIDC. Click on the OIDC button, and you'll be redirected to Pocket ID for authentication. Once authenticated, you'll be redirected back to RomM.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/","title":"With Zitadel","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#oidc-setup-with-zitadel","title":"OIDC Setup With Zitadel","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#a-quick-rundown-of-the-technologies","title":"A quick rundown of the technologies","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#what-is-zitadel","title":"What is Zitadel","text":"

    Zitadel is an enterprise-grade, open-source identity and access management (IAM) platform that supports OAuth2, OpenID Connect, SAML, and passwordless authentication. It's used to manage users, roles, and secure login for web and cloud applications.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#what-is-oauth2","title":"What is OAuth2?","text":"

    OAuth2 (Open Authorization 2.0) is an industry-standard protocol for authorization. It allows applications (clients) to gain limited access to user accounts on an HTTP service without sharing the user\u2019s credentials. Instead, it uses access tokens to facilitate secure interactions. OAuth2 is commonly used in scenarios where users need to authenticate via a third-party service.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#what-is-openid-connect-oidc","title":"What is OpenID Connect (OIDC)?","text":"

    OIDC (OpenID Connect) is an identity layer built on top of OAuth2. While OAuth2 primarily handles authorization, OIDC adds authentication, enabling applications to verify a user\u2019s identity and obtain profile information. This makes OIDC suitable for SSO solutions, where user identity is central to access management.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#setting-up-a-client-in-zitadel","title":"Setting up a client in Zitadel","text":""},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#step-1-install-and-configure-zitadel","title":"Step 1: Install and Configure Zitadel","text":"

    Before setting up the OIDC client, ensure that Zitadel is installed and running by following the setup guide.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#step-2-create-a-project","title":"Step 2: Create a Project","text":"

    Once you have logged in and changed the default password for your Zitadel organization, create a new Project (i.e Romm). This will be the basic settings for roles and authorization.

    In the \"General\" tab, there are options to allow the following:

    Unnecessary: Romm (at this time) does not allow granting permissions based on role, everyone gets viewer and will have to be changed manually using an admin account if desired.

    Recommended: If you allow registration to your platform, then anyone who registers can instantly access Romm (although only as a viewer, which may not be a problem for some)

    Optional: It could be used if you plan on separating users by organizations for other applications, but creating separate organizations is not typically useful for general self-hosting purposes

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#step-25-optional-if-you-enabled-check-authorization-on-authentication-grant-users-access-to-the-project","title":"Step 2.5 (Optional: If you enabled \"Check authorization on Authentication\"): Grant user(s) access to the Project","text":"

    Click on the Authorization tab and click New.

    Enter the user(s) and click Continue

    It should say \"No role has been created yet.\", but this is fine, you can just click Save and it should bring you back to the Authorization page with your user(s) listed with no roles

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#step-3-create-the-application","title":"Step 3: Create the application","text":"

    On the General tab, click the New button under Applications.

    (Check \"I'm a pro. Skip this wizard.\" to enter the information quicker)

    Click Create.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#step-3-configure-romm-environment-variables","title":"Step 3: Configure RomM Environment Variables","text":"

    To enable OIDC authentication in RomM, you need to set the following environment variables:

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#step-4-enable-claims-from-id-token-this-resolves-the-email-is-missing-from-token-error","title":"Step 4: Enable claims from ID Token (this resolves the \"Email is missing from token\" error)","text":"

    Click close to finish creating the application and then go to the Token Settings tab.

    Check \"User Info inside ID Token\" and click Save

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#step-5-set-your-email-in-romm","title":"Step 5: Set your Email in RomM","text":"

    For your existing RomM admin account, open your user profile on Zitadel and set your email address. This email has to match your user email in Zitadel.

    "},{"location":"OIDC-Guides/OIDC-Setup-With-Zitadel/#step-6-test-the-integration","title":"Step 6: Test the Integration","text":"

    After configuring the environment variables, restart (or stop and remove) your RomM instance and navigate to the login page. You should see the option \"LOGIN WITH ZITADEL\". Click on it and you'll be redirected to Zitadel for authentication. Once authenticated, you'll be redirected back to RomM.

    "},{"location":"Platforms-and-Players/Custom-Platforms/","title":"Custom Platforms","text":"

    While RomM supports every platform listed in the Supported Platforms page, the list is not exhaustive, and you may have ROMs in your library for other platforms. To load those files into RomM, place them in a folder for each platform, and give it a name that's all lowercase, with - to separate words, and with no white spaces. For example, pocket-challenge-v2 would map to Pocket Challenge V2, and display the default platform icon in the app.

    Furthermore, only a portion of the supported platforms have custom icons built-in. If your library has platforms that aren't listed in the platforms icons list, RomM will display a default fallback icon.

    If you'd like to load your own custom icons for missing platforms, you can mount /var/www/html/assets/platforms to some local folder and place all of your custom .ico platform icons in there. You'll also want to download the ones provided in this project and place them in the same folder. If you'd like to use your own icons for platforms already supported by RomM, just replace the file with another using the exact same name.

    The name of the .ico file should match the slug of the platform on IGDB. For example, the URL for the AmstradCPC is https://www.igdb.com/platforms/acpc, so the filename should be acpc.ico.

    "},{"location":"Platforms-and-Players/EmulatorJS-Player/","title":"EmulatorJS","text":"

    EmulatorJS is a web-based emulator for various system; that is, it allows you to run old games in your web browser. It's based on RetroArch compiled with Emscripten, which is a toolchain for compiling C and C++ code to WebAssembly.

    Warning

    Note

    Some platforms may require multiple BIOS/firmware files to be loaded at the same time. To do this, create a ZIP archive containing all the firmware files for the emulator you've selected and upload it to the firmware section of the platform. This ZIP file will be recognized by EmulatorJS as the firmware bundle for the platform. Refer to the EmulatorJS documentation for the required list of files for each platform.

    "},{"location":"Platforms-and-Players/EmulatorJS-Player/#saves-and-states","title":"Saves and states","text":"

    Our integration with EmulatorJS automates the process of loading and save files and save states. Before starting the game, select a save and/or state file to load (if one is available). Anytime you manually save the game (or create a save state) by clicking the save or \"save and quit\" buttons, the save and state files stored with RomM will be updated, so there's no need to manually download or upload them.

    "},{"location":"Platforms-and-Players/EmulatorJS-Player/#netplay","title":"Netplay","text":"

    Netplay lets you play with friends remotely, in realtime with the build-in web player. As it emulates playing on the same console with two controllers while streaming the video to players 2+, it's best for 2-player, co-op, turn based and party games.

    Start by enabling netplay in your config.yml:

    emulatorjs:\n    netplay:\n        enabled: true\n

    If you require ICE servers for NAT traversal, we recommend a free-tier Metered account. Create new \"TURN Credentials\" and replace <username> and <password> with the entries under \"Show ICE Server Array\":

    emulatorjs:\n    netplay:\n        ice_servers:\n            - urls: \"stun:stun.relay.metered.ca:80\"\n            - urls: \"stun:stun.relay.metered.ca:80\"\n            - urls: \"turn:global.relay.metered.ca:80\"\n              username: \"<username>\"\n              credential: \"<password>\"\n            - urls: \"turn:global.relay.metered.ca:80?transport=tcp\"\n              username: \"<username>\"\n              credential: \"<password>\"\n            - urls: \"turn:global.relay.metered.ca:443\"\n              username: \"<username>\"\n              credential: \"<password>\"\n            - urls: \"turns:global.relay.metered.ca:443?transport=tcp\"\n              username: \"<username>\"\n              credential: \"<password>\"\n

    Alternatively, use the free STUN servers from Google and TURN servers via the OpenRelayProject:

    emulatorjs:\n    netplay:\n        ice_servers:\n            - urls: \"stun:stun.l.google.com:19302\"\n            - urls: \"stun:stun1.l.google.com:19302\"\n            - urls: \"stun:stun2.l.google.com:19302\"\n            - urls: \"turn:openrelay.metered.ca:80\"\n              username: \"openrelayproject\"\n              credential: \"openrelayproject\"\n            - urls: \"turn:openrelay.metered.ca:443\"\n              username: \"openrelayproject\"\n              credential: \"openrelayproject\"\n

    To host a game, start it, then hit the \ud83c\udf10 icon in botton bar. Set your name, create a room (password optional), and other players should be able to see and join your room. All players need access to your RomM server to join a room and play together.

    "},{"location":"Platforms-and-Players/EmulatorJS-Player/#supported-systems","title":"Supported systems","text":"

    Note that only the following systems are currently supported:

    "},{"location":"Platforms-and-Players/MS-DOS/","title":"MS-DOS","text":"

    DOS is now supported in versions of RomM 4.0 and above thanks to the EmulatorJS player - Simply create a DOS platform to enable the integration

    Info

    I highly suggest you upload the games as .zip as the core can take advantage of unzipping and auto mounting options which are explained more below.

    Info

    Loading and saving states ARE supported so it's possible you only need to do the below steps once to load the game.

    "},{"location":"Platforms-and-Players/MS-DOS/#running-games","title":"Running Games","text":"

    Once you have the play button in the platform available for you there is some additional work you need to do in order to get the games playable and running. You first need to identify what DOS game you are trying to run, there would be three categories

    The official method to run the games from the EmulatorJS dev is the following (Only works for Homebrew and Demos):

    "},{"location":"Platforms-and-Players/MS-DOS/#advanced-running-games","title":"Advanced Running Games","text":"

    Warning

    This is not for the faint of heart and will require a lot of trial and error.

    As the system is using DOSBOX pure it has a neat trick where it will run .CONF files it finds and automatically mount locations and run .exe files automatically, at the minute this is highly experimental and might be more effort then it is worth, but if you want the files running perfectly then I would suggest you look into this method, but it is extremely trail and error.

    When you run a game in DOSBOX Pure, before it runs and mounts anything it will look for a .conf file and follow those instructions, this way we can actually auto mount locations, mount the required CDs and play the game without typing anything, you just click play, the auto mount does everything in the background and you are presented with the game.

    This is an example using the doom shareware file which has all the files in the folder.

    DOOM.conf Example
    # This is the configurationfile for DOSBox 0.74. (Please use the latest version of DOSBox)\n# Lines starting with a # are commentlines and are ignored by DOSBox.\n# They are used to (briefly) document the effect of each option.\n\n[sdl]\n#       fullscreen: Start dosbox directly in fullscreen. (Press ALT-Enter to go back)\n#       fulldouble: Use double buffering in fullscreen. It can reduce screen flickering, but it can also result in a slow DOSBox.\n#   fullresolution: What resolution to use for fullscreen: original or fixed size (e.g. 1024x768).\n#                     Using your monitor's native resolution with aspect=true might give the best results.\n#                     If you end up with small window on a large screen, try an output different from surface.\n# windowresolution: Scale the window to this size IF the output device supports hardware scaling.\n#                     (output=surface does not!)\n#           output: What video system to use for output.\n#                   Possible values: surface, overlay, opengl, openglnb, ddraw.\n#         autolock: Mouse will automatically lock, if you click on the screen. (Press CTRL-F10 to unlock)\n#      sensitivity: Mouse sensitivity.\n#      waitonerror: Wait before closing the console if dosbox has an error.\n#         priority: Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized.\n#                     pause is only valid for the second entry.\n#                   Possible values: lowest, lower, normal, higher, highest, pause.\n#       mapperfile: File used to load/save the key/event mappings from. Resetmapper only works with the defaul value.\n#     usescancodes: Avoid usage of symkeys, might not work on all operating systems.\n\nfullscreen=TRUE\nfulldouble=false\nfullresolution=Fixed\nwindowresolution=1280x800\noutput=direct3d\nautolock=true\nsensitivity=100\nwaitonerror=true\npriority=higher,normal\nmapperfile=mapper-0.74.map\nusescancodes=true\n\n[dosbox]\n# language: Select another language file.\n#  machine: The type of machine tries to emulate.\n#           Possible values: hercules, cga, tandy, pcjr, ega, vgaonly, svga_s3, svga_et3000, svga_et4000, svga_paradise, vesa_nolfb, vesa_oldvbe.\n# captures: Directory where things like wave, midi, screenshot get captured.\n#  memsize: Amount of memory DOSBox has in megabytes.\n#             This value is best left at its default to avoid problems with some games,\n#             though few games might require a higher value.\n#             There is generally no speed advantage when raising this value.\n\nlanguage=\nmachine=svga_s3\ncaptures=.\\Captures\\\nmemsize=16\n\n[render]\n# frameskip: How many frames DOSBox skips before drawing one.\n#    aspect: Do aspect correction, if your output method doesn't support scaling this can slow things down!.\n#    scaler: Scaler used to enlarge/enhance low resolution modes.\n#              If 'forced' is appended, then the scaler will be used even if the result might not be desired.\n#            Possible values: none, normal2x, normal3x, advmame2x, advmame3x, advinterp2x, advinterp3x, hq2x, hq3x, 2xsai, super2xsai, supereagle, tv2x, tv3x, rgb2x, rgb3x, scan2x, scan3x.\n\nframeskip=0\naspect=false\nscaler=normal3x\n\n[cpu]\n#      core: CPU Core used in emulation. auto will switch to dynamic if available and appropriate.\n#            Possible values: auto, dynamic, normal, simple.\n#   cputype: CPU Type used in emulation. auto is the fastest choice.\n#            Possible values: auto, 386, 386_slow, 486_slow, pentium_slow, 386_prefetch.\n#    cycles: Amount of instructions DOSBox tries to emulate each millisecond.\n#            Setting this value too high results in sound dropouts and lags.\n#            Cycles can be set in 3 ways:\n#              'auto'          tries to guess what a game needs.\n#                              It usually works, but can fail for certain games.\n#              'fixed #number' will set a fixed amount of cycles. This is what you usually need if 'auto' fails.\n#                              (Example: fixed 4000).\n#              'max'           will allocate as much cycles as your computer is able to handle.\n#\n#            Possible values: auto, fixed, max.\n#   cycleup: Amount of cycles to decrease/increase with keycombo.(CTRL-F11/CTRL-F12)\n# cycledown: Setting it lower than 100 will be a percentage.\n\ncore=auto\ncputype=auto\ncycles=max\ncycleup=10\ncycledown=20\n\n[mixer]\n#   nosound: Enable silent mode, sound is still emulated though.\n#      rate: Mixer sample rate, setting any device's rate higher than this will probably lower their sound quality.\n#            Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.\n# blocksize: Mixer block size, larger blocks might help sound stuttering but sound will also be more lagged.\n#            Possible values: 1024, 2048, 4096, 8192, 512, 256.\n# prebuffer: How many milliseconds of data to keep on top of the blocksize.\n\nnosound=false\nrate=22050\nblocksize=2048\nprebuffer=10\n\n[midi]\n#     mpu401: Type of MPU-401 to emulate.\n#             Possible values: intelligent, uart, none.\n# mididevice: Device that will receive the MIDI data from MPU-401.\n#             Possible values: default, win32, alsa, oss, coreaudio, coremidi, none.\n# midiconfig: Special configuration options for the device driver. This is usually the id of the device you want to use.\n#               See the README/Manual for more details.\n\nmpu401=intelligent\nmididevice=default\nmidiconfig=\n\n[sblaster]\n#  sbtype: Type of Soundblaster to emulate. gb is Gameblaster.\n#          Possible values: sb1, sb2, sbpro1, sbpro2, sb16, gb, none.\n#  sbbase: The IO address of the soundblaster.\n#          Possible values: 220, 240, 260, 280, 2a0, 2c0, 2e0, 300.\n#     irq: The IRQ number of the soundblaster.\n#          Possible values: 7, 5, 3, 9, 10, 11, 12.\n#     dma: The DMA number of the soundblaster.\n#          Possible values: 1, 5, 0, 3, 6, 7.\n#    hdma: The High DMA number of the soundblaster.\n#          Possible values: 1, 5, 0, 3, 6, 7.\n# sbmixer: Allow the soundblaster mixer to modify the DOSBox mixer.\n# oplmode: Type of OPL emulation. On 'auto' the mode is determined by sblaster type. All OPL modes are Adlib-compatible, except for 'cms'.\n#          Possible values: auto, cms, opl2, dualopl2, opl3, none.\n#  oplemu: Provider for the OPL emulation. compat might provide better quality (see oplrate as well).\n#          Possible values: default, compat, fast.\n# oplrate: Sample rate of OPL music emulation. Use 49716 for highest quality (set the mixer rate accordingly).\n#          Possible values: 44100, 49716, 48000, 32000, 22050, 16000, 11025, 8000.\n\nsbtype=sb16\nsbbase=220\nirq=7\ndma=1\nhdma=5\nsbmixer=true\noplmode=auto\noplemu=default\noplrate=44100\n\n[gus]\n#      gus: Enable the Gravis Ultrasound emulation.\n#  gusrate: Sample rate of Ultrasound emulation.\n#           Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.\n#  gusbase: The IO base address of the Gravis Ultrasound.\n#           Possible values: 240, 220, 260, 280, 2a0, 2c0, 2e0, 300.\n#   gusirq: The IRQ number of the Gravis Ultrasound.\n#           Possible values: 5, 3, 7, 9, 10, 11, 12.\n#   gusdma: The DMA channel of the Gravis Ultrasound.\n#           Possible values: 3, 0, 1, 5, 6, 7.\n# ultradir: Path to Ultrasound directory. In this directory\n#           there should be a MIDI directory that contains\n#           the patch files for GUS playback. Patch sets used\n#           with Timidity should work fine.\n\ngus=false\ngusrate=44100\ngusbase=240\ngusirq=5\ngusdma=3\nultradir=C:\\ULTRASND\n\n[speaker]\n# pcspeaker: Enable PC-Speaker emulation.\n#    pcrate: Sample rate of the PC-Speaker sound generation.\n#            Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.\n#     tandy: Enable Tandy Sound System emulation. For 'auto', emulation is present only if machine is set to 'tandy'.\n#            Possible values: auto, on, off.\n# tandyrate: Sample rate of the Tandy 3-Voice generation.\n#            Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.\n#    disney: Enable Disney Sound Source emulation. (Covox Voice Master and Speech Thing compatible).\n\npcspeaker=true\npcrate=44100\ntandy=auto\ntandyrate=44100\ndisney=true\n\n[joystick]\n# joysticktype: Type of joystick to emulate: auto (default), none,\n#               2axis (supports two joysticks),\n#               4axis (supports one joystick, first joystick used),\n#               4axis_2 (supports one joystick, second joystick used),\n#               fcs (Thrustmaster), ch (CH Flightstick).\n#               none disables joystick emulation.\n#               auto chooses emulation depending on real joystick(s).\n#               (Remember to reset dosbox's mapperfile if you saved it earlier)\n#               Possible values: auto, 2axis, 4axis, 4axis_2, fcs, ch, none.\n#        timed: enable timed intervals for axis. Experiment with this option, if your joystick drifts (away).\n#     autofire: continuously fires as long as you keep the button pressed.\n#       swap34: swap the 3rd and the 4th axis. can be useful for certain joysticks.\n#   buttonwrap: enable button wrapping at the number of emulated buttons.\n\njoysticktype=fcs\ntimed=true\nautofire=false\nswap34=false\nbuttonwrap=false\n\n[serial]\n# serial1: set type of device connected to com port.\n#          Can be disabled, dummy, modem, nullmodem, directserial.\n#          Additional parameters must be in the same line in the form of\n#          parameter:value. Parameter for all types is irq (optional).\n#          for directserial: realport (required), rxdelay (optional).\n#                           (realport:COM1 realport:ttyS0).\n#          for modem: listenport (optional).\n#          for nullmodem: server, rxdelay, txdelay, telnet, usedtr,\n#                         transparent, port, inhsocket (all optional).\n#          Example: serial1=modem listenport:5000\n#          Possible values: dummy, disabled, modem, nullmodem, directserial.\n# serial2: see serial1\n#          Possible values: dummy, disabled, modem, nullmodem, directserial.\n# serial3: see serial1\n#          Possible values: dummy, disabled, modem, nullmodem, directserial.\n# serial4: see serial1\n#          Possible values: dummy, disabled, modem, nullmodem, directserial.\n\nserial1=dummy\nserial2=dummy\nserial3=disabled\nserial4=disabled\n\n[dos]\n#            xms: Enable XMS support.\n#            ems: Enable EMS support.\n#            umb: Enable UMB support.\n# keyboardlayout: Language code of the keyboard layout (or none).\n\nxms=true\nems=true\numb=true\nkeyboardlayout=auto\n\n[ipx]\n# ipx: Enable ipx over UDP/IP emulation.\n\nipx=false\n\n[autoexec]\n# Lines in this section will be run at startup.\n# You can put your MOUNT lines here.\n\n@echo off\nMount C \"..\"\nC:\ncls\nDOOM.exe\n:exit\nexit\n
    "},{"location":"Platforms-and-Players/MS-DOS/#advanced-running-retail-games","title":"Advanced Running Retail Games","text":"

    Info

    At the minute DOS games redesigned by GOG are NOT supported, this is due to how they mount and use the locations. I am looking into how I can figure this out but I have had a 100% failure rate from the GOG DOS Games.

    Retail games usually require to run alongside a disk even if the game has been \"installed\" locally. I will use Dungeon Keeper Gold as an example for a retail game with a disc and the configuration needed.

    KEEPER.conf Example
    # This is the configurationfile for DOSBox 0.74. (Please use the latest version of DOSBox)\n# Lines starting with a # are commentlines and are ignored by DOSBox.\n# They are used to (briefly) document the effect of each option.\n\n[sdl]\n#       fullscreen: Start dosbox directly in fullscreen. (Press ALT-Enter to go back)\n#       fulldouble: Use double buffering in fullscreen. It can reduce screen flickering, but it can also result in a slow DOSBox.\n#   fullresolution: What resolution to use for fullscreen: original or fixed size (e.g. 1024x768).\n#                     Using your monitor's native resolution with aspect=true might give the best results.\n#                     If you end up with small window on a large screen, try an output different from surface.\n# windowresolution: Scale the window to this size IF the output device supports hardware scaling.\n#                     (output=surface does not!)\n#           output: What video system to use for output.\n#                   Possible values: surface, overlay, opengl, openglnb, ddraw.\n#         autolock: Mouse will automatically lock, if you click on the screen. (Press CTRL-F10 to unlock)\n#      sensitivity: Mouse sensitivity.\n#      waitonerror: Wait before closing the console if dosbox has an error.\n#         priority: Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized.\n#                     pause is only valid for the second entry.\n#                   Possible values: lowest, lower, normal, higher, highest, pause.\n#       mapperfile: File used to load/save the key/event mappings from. Resetmapper only works with the defaul value.\n#     usescancodes: Avoid usage of symkeys, might not work on all operating systems.\n\nfullscreen=TRUE\nfulldouble=false\nfullresolution=Fixed\nwindowresolution=1280x800\noutput=direct3d\nautolock=true\nsensitivity=100\nwaitonerror=true\npriority=higher,normal\nmapperfile=mapper-0.74.map\nusescancodes=true\n\n[dosbox]\n# language: Select another language file.\n#  machine: The type of machine tries to emulate.\n#           Possible values: hercules, cga, tandy, pcjr, ega, vgaonly, svga_s3, svga_et3000, svga_et4000, svga_paradise, vesa_nolfb, vesa_oldvbe.\n# captures: Directory where things like wave, midi, screenshot get captured.\n#  memsize: Amount of memory DOSBox has in megabytes.\n#             This value is best left at its default to avoid problems with some games,\n#             though few games might require a higher value.\n#             There is generally no speed advantage when raising this value.\n\nlanguage=\nmachine=svga_s3\ncaptures=.\\Captures\\\nmemsize=16\n\n[render]\n# frameskip: How many frames DOSBox skips before drawing one.\n#    aspect: Do aspect correction, if your output method doesn't support scaling this can slow things down!.\n#    scaler: Scaler used to enlarge/enhance low resolution modes.\n#              If 'forced' is appended, then the scaler will be used even if the result might not be desired.\n#            Possible values: none, normal2x, normal3x, advmame2x, advmame3x, advinterp2x, advinterp3x, hq2x, hq3x, 2xsai, super2xsai, supereagle, tv2x, tv3x, rgb2x, rgb3x, scan2x, scan3x.\n\nframeskip=0\naspect=false\nscaler=normal3x\n\n[cpu]\n#      core: CPU Core used in emulation. auto will switch to dynamic if available and appropriate.\n#            Possible values: auto, dynamic, normal, simple.\n#   cputype: CPU Type used in emulation. auto is the fastest choice.\n#            Possible values: auto, 386, 386_slow, 486_slow, pentium_slow, 386_prefetch.\n#    cycles: Amount of instructions DOSBox tries to emulate each millisecond.\n#            Setting this value too high results in sound dropouts and lags.\n#            Cycles can be set in 3 ways:\n#              'auto'          tries to guess what a game needs.\n#                              It usually works, but can fail for certain games.\n#              'fixed #number' will set a fixed amount of cycles. This is what you usually need if 'auto' fails.\n#                              (Example: fixed 4000).\n#              'max'           will allocate as much cycles as your computer is able to handle.\n#\n#            Possible values: auto, fixed, max.\n#   cycleup: Amount of cycles to decrease/increase with keycombo.(CTRL-F11/CTRL-F12)\n# cycledown: Setting it lower than 100 will be a percentage.\n\ncore=auto\ncputype=auto\ncycles=max\ncycleup=10\ncycledown=20\n\n[mixer]\n#   nosound: Enable silent mode, sound is still emulated though.\n#      rate: Mixer sample rate, setting any device's rate higher than this will probably lower their sound quality.\n#            Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.\n# blocksize: Mixer block size, larger blocks might help sound stuttering but sound will also be more lagged.\n#            Possible values: 1024, 2048, 4096, 8192, 512, 256.\n# prebuffer: How many milliseconds of data to keep on top of the blocksize.\n\nnosound=false\nrate=22050\nblocksize=2048\nprebuffer=10\n\n[midi]\n#     mpu401: Type of MPU-401 to emulate.\n#             Possible values: intelligent, uart, none.\n# mididevice: Device that will receive the MIDI data from MPU-401.\n#             Possible values: default, win32, alsa, oss, coreaudio, coremidi, none.\n# midiconfig: Special configuration options for the device driver. This is usually the id of the device you want to use.\n#               See the README/Manual for more details.\n\nmpu401=intelligent\nmididevice=default\nmidiconfig=\n\n[sblaster]\n#  sbtype: Type of Soundblaster to emulate. gb is Gameblaster.\n#          Possible values: sb1, sb2, sbpro1, sbpro2, sb16, gb, none.\n#  sbbase: The IO address of the soundblaster.\n#          Possible values: 220, 240, 260, 280, 2a0, 2c0, 2e0, 300.\n#     irq: The IRQ number of the soundblaster.\n#          Possible values: 7, 5, 3, 9, 10, 11, 12.\n#     dma: The DMA number of the soundblaster.\n#          Possible values: 1, 5, 0, 3, 6, 7.\n#    hdma: The High DMA number of the soundblaster.\n#          Possible values: 1, 5, 0, 3, 6, 7.\n# sbmixer: Allow the soundblaster mixer to modify the DOSBox mixer.\n# oplmode: Type of OPL emulation. On 'auto' the mode is determined by sblaster type. All OPL modes are Adlib-compatible, except for 'cms'.\n#          Possible values: auto, cms, opl2, dualopl2, opl3, none.\n#  oplemu: Provider for the OPL emulation. compat might provide better quality (see oplrate as well).\n#          Possible values: default, compat, fast.\n# oplrate: Sample rate of OPL music emulation. Use 49716 for highest quality (set the mixer rate accordingly).\n#          Possible values: 44100, 49716, 48000, 32000, 22050, 16000, 11025, 8000.\n\nsbtype=sb16\nsbbase=220\nirq=7\ndma=1\nhdma=5\nsbmixer=true\noplmode=auto\noplemu=default\noplrate=44100\n\n[gus]\n#      gus: Enable the Gravis Ultrasound emulation.\n#  gusrate: Sample rate of Ultrasound emulation.\n#           Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.\n#  gusbase: The IO base address of the Gravis Ultrasound.\n#           Possible values: 240, 220, 260, 280, 2a0, 2c0, 2e0, 300.\n#   gusirq: The IRQ number of the Gravis Ultrasound.\n#           Possible values: 5, 3, 7, 9, 10, 11, 12.\n#   gusdma: The DMA channel of the Gravis Ultrasound.\n#           Possible values: 3, 0, 1, 5, 6, 7.\n# ultradir: Path to Ultrasound directory. In this directory\n#           there should be a MIDI directory that contains\n#           the patch files for GUS playback. Patch sets used\n#           with Timidity should work fine.\n\ngus=false\ngusrate=44100\ngusbase=240\ngusirq=5\ngusdma=3\nultradir=C:\\ULTRASND\n\n[speaker]\n# pcspeaker: Enable PC-Speaker emulation.\n#    pcrate: Sample rate of the PC-Speaker sound generation.\n#            Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.\n#     tandy: Enable Tandy Sound System emulation. For 'auto', emulation is present only if machine is set to 'tandy'.\n#            Possible values: auto, on, off.\n# tandyrate: Sample rate of the Tandy 3-Voice generation.\n#            Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.\n#    disney: Enable Disney Sound Source emulation. (Covox Voice Master and Speech Thing compatible).\n\npcspeaker=true\npcrate=44100\ntandy=auto\ntandyrate=44100\ndisney=true\n\n[joystick]\n# joysticktype: Type of joystick to emulate: auto (default), none,\n#               2axis (supports two joysticks),\n#               4axis (supports one joystick, first joystick used),\n#               4axis_2 (supports one joystick, second joystick used),\n#               fcs (Thrustmaster), ch (CH Flightstick).\n#               none disables joystick emulation.\n#               auto chooses emulation depending on real joystick(s).\n#               (Remember to reset dosbox's mapperfile if you saved it earlier)\n#               Possible values: auto, 2axis, 4axis, 4axis_2, fcs, ch, none.\n#        timed: enable timed intervals for axis. Experiment with this option, if your joystick drifts (away).\n#     autofire: continuously fires as long as you keep the button pressed.\n#       swap34: swap the 3rd and the 4th axis. can be useful for certain joysticks.\n#   buttonwrap: enable button wrapping at the number of emulated buttons.\n\njoysticktype=fcs\ntimed=true\nautofire=false\nswap34=false\nbuttonwrap=false\n\n[serial]\n# serial1: set type of device connected to com port.\n#          Can be disabled, dummy, modem, nullmodem, directserial.\n#          Additional parameters must be in the same line in the form of\n#          parameter:value. Parameter for all types is irq (optional).\n#          for directserial: realport (required), rxdelay (optional).\n#                           (realport:COM1 realport:ttyS0).\n#          for modem: listenport (optional).\n#          for nullmodem: server, rxdelay, txdelay, telnet, usedtr,\n#                         transparent, port, inhsocket (all optional).\n#          Example: serial1=modem listenport:5000\n#          Possible values: dummy, disabled, modem, nullmodem, directserial.\n# serial2: see serial1\n#          Possible values: dummy, disabled, modem, nullmodem, directserial.\n# serial3: see serial1\n#          Possible values: dummy, disabled, modem, nullmodem, directserial.\n# serial4: see serial1\n#          Possible values: dummy, disabled, modem, nullmodem, directserial.\n\nserial1=dummy\nserial2=dummy\nserial3=disabled\nserial4=disabled\n\n[dos]\n#            xms: Enable XMS support.\n#            ems: Enable EMS support.\n#            umb: Enable UMB support.\n# keyboardlayout: Language code of the keyboard layout (or none).\n\nxms=true\nems=true\numb=true\nkeyboardlayout=auto\n\n[ipx]\n# ipx: Enable ipx over UDP/IP emulation.\n\nipx=false\n\n[autoexec]\n# Lines in this section will be run at startup.\n# You can put your MOUNT lines here.\n\n@echo off\nMount C \"..\"\nC:\ncd CD\nimgmount d DUNGEO~8.CUE -t iso -fs iso\ncd ..\ncls\nKEEPER.exe\n:exit\nexit\n
    "},{"location":"Platforms-and-Players/MS-DOS/#advanced-game-troubleshooting","title":"Advanced Game Troubleshooting","text":"

    If the games are not working and you go back to a blank dos looking screen, this will require some manual troubleshooting but I have found success with the following methods:

    Another way of troubleshooting is to use Retroarch and the core \"dosbox-pure\" because if it runs in here, it will run in RomM. Simply give it your ZIP and it will act the same as if you was doing it through RomM, once the .conf file is perfected add it back to the ZIP.

    "},{"location":"Platforms-and-Players/RuffleRS-Player/","title":"RuffleRS","text":"

    Ruffle is a web-based player for flash games. With flash now discontinued, this is the best way to play your flash collection in the browser.

    Important

    Ruffle will only play games stored in platform folders called flash or browser.

    "},{"location":"Platforms-and-Players/Supported-Platforms/","title":"Supported Platforms","text":"

    Below is a list of all supported platforms/systems/consoles and their respective folder names. Supported platforms means RomM can fetch metadata from sources for those platforms.

    Info

    For platforms that can be playable in the browser, please check EmulatorJS supported platforms and RuffleRS player.

    Danger

    The folder name is case-sensitive and must be used exactly as it appears in the list below.

    Filter providers

    0 of 0 platforms shown Platform Name Folder Name Metadata Providers 1292 Advanced Programmable Video System 1292-advanced-programmable-video-system 3DO Interactive Multiplayer 3do 8-Bit Productions Commander X16 commander-x16 Aamber Pegasus pegasus ABC 80 abc-80 Acorn Archimedes acorn-archimedes Acorn Electron acorn-electron Advanced Pico Beena advanced-pico-beena Adventure Vision adventure-vision AirConsole airconsole Alice 32/90 alice-3290 Altair 680 altair-680 Altair 8800 altair-8800 Amazon Alexa amazon-alexa Amazon Fire TV amazon-fire-tv Amiga amiga Amiga CD amiga-cd Amiga CD32 amiga-cd32 Amstrad CPC acpc Amstrad GX4000 amstrad-gx4000 Amstrad PCW amstrad-pcw Analogue electronics analogueelectronics Android android Antstream antstream APF MP1000/Imagination Machine apf Apogee BK-01 bk-01 Apple I apple Apple II appleii Apple IIGS apple-iigs Apple III appleiii Apple Lisa apple-lisa Apple Pippin apple-pippin Arcade arcade Arcadia 2001 arcadia-2001 Arduboy arduboy Astral 2000 astral-2000 Atari 2600 atari2600 Atari 5200 atari5200 Atari 7800 atari7800 Atari 8-bit atari8bit Atari 800 atari800 Atari Jaguar jaguar Atari Jaguar CD atari-jaguar-cd Atari Lynx lynx Atari ST/STE atari-st Atari VCS atari-vcs Atari XEGS atari-xegs Atom atom AY-3-8500 ay-3-8500 AY-3-8603 ay-3-8603 AY-3-8605 ay-3-8605 AY-3-8606 ay-3-8606 AY-3-8607 ay-3-8607 AY-3-8610 ay-3-8610 AY-3-8710 ay-3-8710 AY-3-8760 ay-3-8760 Bada bada Bally Astrocade astrocade BBC Microcomputer System bbcmicro Benesse Pocket Challenge V2 pocket-challenge-v2 Benesse Pocket Challenge W pocket-challenge-w BeOS beos BGR Computers Excalibur 64 excalibur-64 Bit Corporation BIT 90 bit-90 Black Point black-point BlackBerry OS blackberry Blacknut blacknut Blu-ray Player blu-ray-player BREW brew Browser (Flash/HTML5) browser Bubble bubble Call-A-Computer time-shared mainframe computer system call-a-computer Cambridge Computer Z88 z88 Camputers Lynx camputers-lynx Casio CFX-9850 casio-cfx-9850 Casio FP-1000 & FP-1100 casio-fp-1000 Casio Loopy casio-loopy Casio PB-1000 casio-pb-1000 Casio Programmable Calculator casio-programmable-calculator Casio PV-1000 casio-pv-1000 Casio PV-2000 casio-pv-2000 CDC Cyber 70 cdccyber70 Champion 2711 champion-2711 ClickStart clickstart Coleco Adam colecoadam ColecoVision colecovision Colour Genie colour-genie Commodore 128 c128 Commodore 16 c16 Commodore C64/128/MAX c64 Commodore CDTV commodore-cdtv Commodore PET cpet Commodore Plus/4 c-plus-4 Commodore VIC-20 vic-20 Compal 80 compal-80 Compucolor I compucolor-i Compucolor II compucolor-ii Compucorp Programmable Calculator compucorp-programmable-calculator COSMAC fred-cosmac CP/M cpm CreatiVision creativision Cybervision cybervision Danger OS danger-os Daydream daydream DEC GT40 gt40 Dedicated console dedicated-console Dedicated handheld dedicated-handheld Didj didj Digiblast digiblast DoJa doja Donner Model 30 donner30 DOS dos Dragon 32/64 dragon-32-slash-64 Dreamcast dc DVD Player dvd-player e-Reader / Card-e Reader e-reader-slash-card-e-reader ECD Micromind ecd-micromind EDSAC edsac Elektor TV Games Computer elektor Elektronika BK bk Enterprise enterprise Epoch Cassette Vision epoch-cassette-vision Epoch Game Pocket Computer epoch-game-pocket-computer Epoch Super Cassette Vision epoch-super-cassette-vision Evercade evercade Exelvision exelvision ExEn exen Exidy Sorcerer exidy-sorcerer Fairchild Channel F fairchild-channel-f Family Computer famicom Family Computer Disk System fds Feature phone mobile-custom Ferranti Nimrod Computer nimrod FM Towns fm-towns FM-7 fm-7 Freebox freebox G-cluster g-cluster Galaksija galaksija Gamate gamate Game & Watch g-and-w Game Boy gb Game Boy Advance gba Game Boy Color gbc Game Master hartung Game Wave game-wave Game.com game-dot-com GameStick gamestick Gear VR gear-vr GIMINI gimini Gizmondo gizmondo Gloud gloud Glulx glulx GNEX gnex Google Stadia stadia GP2X gp2x GP2X Wiz gp2x-wiz GP32 gp32 GVM gvm Handheld Electronic LCD handheld-electronic-lcd HD DVD Player hd-dvd-player Heath/Zenith H8/H89 heathzenith Heathkit H11 heathkit-h11 Hector HRX hrx Hitachi S1 hitachi-s1 HP 2100 hp2100 HP 3000 hp3000 HP 9800 hp-9800 HP Programmable Calculator hp-programmable-calculator Hugo hugo Hyper Neo Geo 64 hyper-neo-geo-64 HyperScan hyperscan IBM 5100 ibm-5100 IBM PCjr pc-jr Ideal-Computer ideal-computer iiRcade iircade Imlac PDS-1 imlac-pds1 Intel 8008 intel-8008 Intel 8080 intel-8080 Intel 8086 / 8088 intel-8086 Intellivision intellivision Intellivision Amico intellivision-amico Interact Model One interact-model-one Interton VC 4000 interton-vc-4000 Interton Video 2000 interton-video-2000 iOS ios iPad ipad iPod Classic ipod-classic J2ME j2me Jolt jolt Jupiter Ace jupiter-ace KaiOS kaios KIM-1 kim-1 Kindle Classic kindle Laser 200 laser200 LaserActive laseractive LeapFrog Explorer leapfrog-explorer Leapster leapster Leapster Explorer/LeadPad Explorer leapster-explorer-slash-leadpad-explorer LeapTV leaptv Legacy Computer legacy-computer Legacy Mobile Device mobile Linux linux Luna luna Mac mac Maemo maemo Magnavox Odyssey odyssey Mainframe mainframe Matsushita/Panasonic JR matsushitapanasonic-jr Mattel Aquarius aquarius MeeGo meego Mega Duck/Cougar Boy mega-duck-slash-cougar-boy Memotech MTX memotech-mtx Memotech MTX512 mtx512 Meritum meritum Meta Quest 2 meta-quest-2 Meta Quest 3 meta-quest-3 Microbee microbee Microcomputer microcomputer Microsoft MSX2+ msx2plus Microtan 65 microtan-65 Microvision microvision Mophun mophun MOS Technology 6502 mos-technology-6502 Motorola 6800 motorola-6800 Motorola 68k motorola-68k MRE mre MSX msx MSX Turbo R msx-turbo MSX2 msx2 MUGEN mugen N-Gage ngage N-Gage (service) ngage2 Namco System 22 system-32 Nascom nascom NEC PC-6000 Series nec-pc-6000-series Neo Geo AES neogeoaes Neo Geo CD neo-geo-cd Neo Geo MVS neogeomvs Neo Geo Pocket neo-geo-pocket Neo Geo Pocket Color neo-geo-pocket-color Neo Geo X neo-geo-x New Nintendo 3DS new-nintendo-3ds NewBrain newbrain Newton newton Nintendo 3DS 3ds Nintendo 64 n64 Nintendo 64DD 64dd Nintendo DS nds Nintendo DSi nintendo-dsi Nintendo Entertainment System nes Nintendo GameCube ngc Nintendo Switch switch Nintendo Switch 2 switch-2 North Star northstar Noval 760 noval-760 Nuon nuon Oculus Go oculus-go Oculus Quest oculus-quest Oculus Rift oculus-rift Oculus VR oculus-vr Odyssey 2 odyssey-2 Ohio Scientific ohio-scientific OnLive Game System onlive-game-system OOParts ooparts OpenBOR openbor Orao orao Oric oric Oric Atmos atmos OS/2 os2 Othello Multivision multivision Ouya ouya Palm OS palm-os Palmtex palmtex Panasonic Jungle panasonic-jungle Panasonic M2 panasonic-m2 Pandora pandora PC Booter pc-booter PC Engine SuperGrafx supergrafx PC-50X Family pc-50x-family PC-6001 pc-6001 PC-8000 pc-8000 PC-8800 Series pc-8800-series PC-9800 Series pc-9800-series PC-FX pc-fx PDP-1 pdp1 PDP-10 pdp10 PDP-11 pdp11 PDP-7 pdp-7 PDP-8 pdp-8 Pebble pebble Philips CD-i philips-cd-i Philips VG 5000 philips-vg-5000 Photo CD photocd PICO pico Pinball pinball Pippin pippin PLATO plato Playdate playdate Playdia playdia PlayStation psx PlayStation 2 ps2 PlayStation 3 ps3 PlayStation 4 ps4 PlayStation 5 ps5 PlayStation Now playstation-now PlayStation Portable psp PlayStation Vita psvita PlayStation VR psvr PlayStation VR2 psvr2 Plex Arcade plex-arcade Plug & Play plug-and-play PocketStation pocketstation Pokitto pokitto Pok\u00e9mon mini pokemon-mini Poly-88 poly-88 Polymega polymega R-Zone r-zone RCA Studio II rca-studio-ii Research Machines 380Z research-machines-380z Roku roku SAM Coup\u00e9 sam-coupe Satellaview satellaview SC/MP scmp ScummVM scummvm SD-200/270/290 sd-200270290 SDS Sigma 7 sdssigma7 Sega 32X sega32 Sega Advanced Pico Beena beena Sega CD segacd Sega CD 32X segacd32 Sega Dreamcast VMU vmu Sega Game Gear gamegear Sega Hikaru hikaru Sega Master System/Mark III sms Sega Mega Drive/Genesis genesis Sega Model 1 model1 Sega Model 2 model2 Sega Model 3 model3 Sega Pico sega-pico Sega Saturn saturn Sega SC-3000 sc3000 Sega ST-V stv Sega System 16 system16 Sega System 32 system32 SG-1000 sg1000 Sharp MZ-2200 sharp-mz-2200 Sharp MZ-80B/2000/2500 sharp-mz-80b20002500 Sharp MZ-80K/700/800/1500 sharp-mz-80k7008001500 Sharp X1 x1 Sharp X68000 sharp-x68000 Sharp Zaurus sharp-zaurus Signetics 2650 signetics-2650 Sinclair QL sinclair-ql Sinclair ZX81 zx81 SK-VM sk-vm SMC-777 smc-777 Socrates socrates Sol-20 sol-20 Sony PSP Minis psp-minis Sord M5 sord-m5 Spectravideo spectravideo SRI-500/1000 sri-5001000 SteamVR steam-vr Sufami Turbo sufami-turbo Super A'Can super-acan Super Famicom sfam Super NES CD-ROM System super-nes-cd-rom-system Super Nintendo Entertainment System snes Super Vision 8000 super-vision-8000 Sure Shot HD sure-shot-hd SwanCrystal swancrystal SWTPC 6800 swtpc-6800 Symbian symbian TADS tads Taito Type X type-x Taito X-55 taito-x-55 Tandy Vis tandy-vis Tapwave Zodiac zod Tatung Einstein tatung-einstein Tektronix 4050 tektronix-4050 Tele-Spiel ES-2201 tele-spiel Telstar Arcade telstar-arcade Terebikko / See 'n Say Video Phone terebikko-slash-see-n-say-video-phone Terminal terminal Texas Instruments TI-82 ti-82 Texas Instruments TI-83 ti-83 Texas Instruments TI-99 ti-99 Thomson MO5 thomson-mo5 Thomson TO thomson-to TI Programmable Calculator ti-programmable-calculator TI-99/4A ti-994a Tiki 100 tiki-100 TIM tim Timex Sinclair 2068 timex-sinclair-2068 Tizen tizen Tomahawk F1 tomahawk-f1 Tomy Tutor tomy-tutor Tomy Tutor / Pyuta / Grandstand Tutor tomy-tutor-slash-pyuta-slash-grandstand-tutor Triton triton TRS-80 trs-80 TRS-80 Color Computer trs-80-color-computer TRS-80 MC-10 trs-80-mc-10 TRS-80 Model 100 trs-80-model-100 TurboGrafx-16/PC Engine tg16 Turbografx-16/PC Engine CD turbografx-cd tvOS tvos Uzebox uzebox V.Flash vflash V.Smile vsmile VC 4000 vc-4000 Vector-06C 06c Vectrex vectrex Versatile versatile VideoBrain videobrain Videopac+ G7400 videopac-g7400 Virtual Boy virtualboy Virtual Console vc VIS vis visionOS visionos Visual Memory Unit / Visual Memory System visual-memory-unit-slash-visual-memory-system Wang 2200 wang2200 WASM-4 wasm-4 Watara/QuickShot Supervision supervision watchOS watchos webOS webos Wii wii Wii U wiiu Windows win Windows 3.x win3x Windows Apps windows-apps Windows Mixed Reality windows-mixed-reality Windows Mobile windows-mobile Windows Phone winphone WIPI wipi WonderSwan wonderswan WonderSwan Color wonderswan-color WoW Action Max action-max XaviXPORT xavixport Xbox xbox Xbox 360 xbox360 Xbox Cloud Gaming xboxcloudgaming Xbox One xboxone Xbox Series X/S series-x-s Xerox Alto xerox-alto Z-machine z-machine Zeebo zeebo Zilog Z80 z80 Zilog Z8000 zilog-z8000 ZiNc zinc Zodiac zodiac Zune zune ZX Spectrum zxs ZX Spectrum Next zx-spectrum-next ZX80 zx80"},{"location":"System-Setup/Synology-Setup-Guide/","title":"Synology Setup","text":""},{"location":"System-Setup/Synology-Setup-Guide/#external-written-guides","title":"External Written Guides","text":"

    While you can follow the below guide, Marius Bogdan Lixandru has written excellent guides which focus on Synology infrastructure and with support for both MariaDB and PostGresSQL:

    We suggest following the above guides if they fit your setup, and the guide below is available for all other use cases.

    "},{"location":"System-Setup/Synology-Setup-Guide/#prerequisites","title":"Prerequisites","text":"

    This guide assumes you're familiar with Docker and have basic knowledge of server management. You'll need:

    "},{"location":"System-Setup/Synology-Setup-Guide/#setup-process","title":"Setup Process","text":""},{"location":"System-Setup/Synology-Setup-Guide/#1-folder-structure-setup","title":"1. Folder Structure Setup","text":""},{"location":"System-Setup/Synology-Setup-Guide/#rom-storage-folders","title":"ROM Storage Folders","text":"

    Create the following directory structure for game assets and configuration:

    mkdir -p /volume1/data/media/games/assets\nmkdir -p /volume1/data/media/games/config\n
    "},{"location":"System-Setup/Synology-Setup-Guide/#rom-library-structure","title":"ROM Library Structure","text":"

    RomM requires a very specific folder structure for rom files:

    mkdir -p /volume1/data/media/games/library/roms\nmkdir -p /volume1/data/media/games/library/bios\n

    Note: For supported platforms and their specific folder names, refer to the official RomM docs.

    "},{"location":"System-Setup/Synology-Setup-Guide/#docker-data-folders","title":"Docker Data Folders","text":"

    Create these folders for project and container data:

    mkdir -p /volume1/docker/romm-project/\nmkdir -p /volume1/docker/romm/resources\nmkdir -p /volume1/docker/romm/redis-data\nmkdir -p /volume1/docker/mariadb-romm\n
    "},{"location":"System-Setup/Synology-Setup-Guide/#2-network-bridge-setup","title":"2. Network Bridge Setup","text":"

    Create a new network bridge named rommbridge following standard Docker networking practices. You can use this guide for reference.

    "},{"location":"System-Setup/Synology-Setup-Guide/#3-key-generation","title":"3. Key Generation","text":""},{"location":"System-Setup/Synology-Setup-Guide/#authentication-key","title":"Authentication Key","text":"

    Generate your authentication key using:

    openssl rand -hex 32\n> 03a054b6ca27e0107c5eed552ea66bacd9f3a2a8a91e7595cd462a593f9ecd09\n

    Save the output - you'll need it for the ROMM_AUTH_SECRET_KEY in your configuration.

    "},{"location":"System-Setup/Synology-Setup-Guide/#api-integration-setup","title":"API Integration Setup","text":"

    Follow the dedicated docs page for API key generation to set up your API keys.

    "},{"location":"System-Setup/Synology-Setup-Guide/#4-mariadb-configuration","title":"4. MariaDB Configuration","text":"

    Important

    "},{"location":"System-Setup/Synology-Setup-Guide/#5-docker-compose-configuration","title":"5. Docker Compose Configuration","text":"

    Create a docker-compose.yml file with the following content:

    Example Docker Compose
    version: \"3\"\n\nvolumes:\n    mysql_data:\n\nservices:\n    romm:\n        image: rommapp/romm:latest\n        container_name: romm\n        restart: unless-stopped\n        environment:\n            - DB_HOST=romm-db\n            - DB_NAME=romm # Should match MARIADB_DATABASE in mariadb\n            - DB_USER=romm-user # Should match MARIADB_USER in mariadb\n            - DB_PASSWD= # Should match MARIADB_PASSWORD in mariadb\n            - ROMM_AUTH_SECRET_KEY= # Generate a key with `openssl rand -hex 32`\n            - SCREENSCRAPER_USER= # These are the recommended metadata providers\n            - SCREENSCRAPER_PASSWORD= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#screenscraper\n            - RETROACHIEVEMENTS_API_KEY= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#retroachievements\n            - STEAMGRIDDB_API_KEY= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#steamgriddb\n            - HASHEOUS_API_ENABLED=true # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#hasheous\n        volumes:\n            - /volume1/docker/romm/resources:/romm/resources\n            - /volume1/docker/romm/redis-data:/redis-data\n            - /volume1/data/media/games/library:/romm/library\n            - /volume1/data/media/games/assets:/romm/assets\n            - /volume1/data/media/games/config:/romm/config\n        ports:\n            - 7676:8080\n        network_mode: rommbridge\n        depends_on:\n            romm-db:\n                condition: service_healthy\n                restart: true\n\n    romm-db:\n        image: mariadb:latest\n        container_name: romm-db\n        restart: unless-stopped\n        environment:\n            - MARIADB_ROOT_PASSWORD= # Use a unique, secure password\n            - MARIADB_DATABASE=romm\n            - MARIADB_USER=romm-user\n            - MARIADB_PASSWORD=\n        ports:\n            - 3309:3306\n        network_mode: rommbridge\n        volumes:\n            - /volume1/docker/mariadb-romm:/var/lib/mysql\n        healthcheck:\n            test: [CMD, healthcheck.sh, --connect, --innodb_initialized]\n            start_period: 30s\n            start_interval: 10s\n            interval: 10s\n            timeout: 5s\n            retries: 5\n
    "},{"location":"System-Setup/Synology-Setup-Guide/#6-initial-launch","title":"6. Initial Launch","text":"
    1. Start the containers using Docker Compose
    2. Be patient! The container can take a few minutes to setup on first launch
    3. Monitor progress through container logs
    4. Access RomM through your browser at http://your-server-ip:7676

    Important

    "},{"location":"System-Setup/Synology-Setup-Guide/#troubleshooting","title":"Troubleshooting","text":""},{"location":"System-Setup/Synology-Setup-Guide/#contributing","title":"Contributing","text":"

    This guide is an abridged version of ChopFoo's original guide. If you have any suggestions or improvements, please submit a pull request to the RomM docs.

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/","title":"TrueNAS Setup","text":""},{"location":"System-Setup/TrueNAS-Setup-Guide/#prerequisites","title":"Prerequisites","text":"

    This guide assumes you're familiar with Docker and have basic knowledge of TrueNAS. You'll need:

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#setup-process","title":"Setup Process","text":""},{"location":"System-Setup/TrueNAS-Setup-Guide/#install-through-the-truenas-app-catalog-recommended","title":"Install through the TrueNAS App Catalog (Recommended)","text":""},{"location":"System-Setup/TrueNAS-Setup-Guide/#step-1-navigate-to-romm-app","title":"Step 1: Navigate to RomM app","text":"

    Navigate to the App Catalog via Apps (Left navigation bar) -> Discover Apps -> RomM -> Install

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#step-2-installation-configuration","title":"Step 2: Installation configuration","text":"

    Step through the installation UI. You will need to supply various credentials per the Quick Start Guide. Most of the default values will work.

    Note: You will likely want to set certain Storage Configurations to a Dataset within TrueNAS, such as your RomM Library and Assets storage. If you do this, ensure you provide ACL access to the UserID specified above (default: 568, apps user).

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#step-3-save-your-configuration","title":"Step 3: Save your configuration","text":"

    Save, and you're done! If the app will not boot, refer to Troubleshooting or head on over to the Discord.

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#install-via-yaml","title":"Install via YAML","text":"

    This installation path should only be used in the event that there is a bug with installing through the App Catalog, or you wish to have more flexibility than is provided by the installation UI.

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#step-1-navigate-to-yaml-install","title":"Step 1: Navigate to YAML install","text":"

    Navigate to the Install via YAML page via Apps (Left navigation bar) -> Discover Apps -> Install via YAML

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#step-2-paste-in-the-following-yml","title":"Step 2: Paste in the following YML","text":"

    Replace any empty values with credentials you've created per the Quick Start Guide.

    Example Docker Compose
    version: \"3\"\n\nvolumes:\n    mysql_data:\n    romm_redis_data:\n\nservices:\n    romm:\n        image: rommapp/romm:latest\n        container_name: romm\n        restart: unless-stopped\n        user: 568:568\n        environment:\n            - DB_HOST=romm-db\n            - DB_NAME=romm # Should match MARIADB_DATABASE in mariadb\n            - DB_USER=romm-user # Should match MARIADB_USER in mariadb\n            - DB_PASSWD= # Should match MARIADB_PASSWORD in mariadb\n            - ROMM_AUTH_SECRET_KEY= # Generate a key with `openssl rand -hex 32`\n            - SCREENSCRAPER_USER= # These are the recommended metadata providers\n            - SCREENSCRAPER_PASSWORD= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#screenscraper\n            - RETROACHIEVEMENTS_API_KEY= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#retroachievements\n            - STEAMGRIDDB_API_KEY= # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#steamgriddb\n            - HASHEOUS_API_ENABLED=true # https://docs.romm.app/latest/Getting-Started/Metadata-Providers/#hasheous\n        volumes: # Any /mnt paths may optionally be replaced with a docker volume\n            - /mnt/tank/truenas/resources:/romm/resources # Replace /mnt...: file path with your own data structure\n            - romm_redis_data:/romm/redis-data # Docker will manage this volume\n            - /mnt/tank/truenas/roms:/romm/library # Replace /mnt...: file path with your own data structure\n            - /mnt/tank/truenas/assets:/romm/assets # Replace /mnt...: file path with your own data structure\n            - /mnt/tank/truenas/config:/romm/config # Replace /mnt...: file path with your own data structure\n        ports:\n            - 31100:8080\n        depends_on:\n            romm-db:\n                condition: service_healthy\n                restart: true\n        deploy:\n            resources:\n                limits:\n                    cpus: \"2.0\"\n                    memory: 4g\n\n    romm-db:\n        image: mariadb:latest\n        container_name: romm-db\n        restart: unless-stopped\n        environment:\n            - MARIADB_ROOT_PASSWORD= # Use a unique, secure password\n            - MARIADB_DATABASE=romm\n            - MARIADB_USER=romm-user\n            - MARIADB_PASSWORD=\n        volumes:\n            - mysql_data:/var/lib/mysql\n        healthcheck:\n            test: [CMD, healthcheck.sh, --connect, --innodb_initialized]\n            start_period: 30s\n            start_interval: 10s\n            interval: 10s\n            timeout: 5s\n            retries: 5\n
    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#step-3-save-the-configuration","title":"Step 3: Save the configuration","text":"

    Save, and you're done! If the app will not boot, refer to Troubleshooting or head on over to the Discord.

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#troubleshooting","title":"Troubleshooting","text":""},{"location":"System-Setup/TrueNAS-Setup-Guide/#general","title":"General","text":""},{"location":"System-Setup/TrueNAS-Setup-Guide/#specific-issues","title":"Specific Issues","text":""},{"location":"System-Setup/TrueNAS-Setup-Guide/#permissions-issues-inside-the-docker-image","title":"Permissions issues inside the docker image","text":"

    If you are encountering permissions issues with folders internal to the docker image (not your TrueNAS dataset), consider temporarily setting the user to root (user: 0). If you do this, it is recommended you fix local file permissions via shell and return access back to a non-root user.

    In my particular setup, I had to create a user/group in TrueNAS with uid:gid of 1000:1000 and auxiliary group apps due to hard-coded values in the RomM docker image. This resolved outstanding issues I had with my instance of RomM talking to its Redis instance.

    "},{"location":"System-Setup/TrueNAS-Setup-Guide/#contributing","title":"Contributing","text":"

    If you have any suggestions or improvements, please submit a pull request to the RomM docs.

    "},{"location":"System-Setup/Unraid-Compose-Setup/","title":"With Docker Compose","text":""},{"location":"System-Setup/Unraid-Compose-Setup/#prerequisites","title":"Prerequisites","text":"

    Before getting started, install the Community Apps plugin for Unraid.

    Install Docker Compose Addon from the CA (Community Apps Store)

    "},{"location":"System-Setup/Unraid-Compose-Setup/#docker-tab","title":"Docker Tab","text":"

    You will now see Compose option under the Docker Containers in your Docker Tab in Unraid

    "},{"location":"System-Setup/Unraid-Compose-Setup/#installation","title":"Installation","text":"

    Click Add New Stack

    Warning

    You need to make sure you are following either Folder Structure A or B (Recommend A Type) RomM Folder Structure

    Warning

    It's strongly recommended to backup the appdata folder (or mount it in a safe location) before updating, since tearing down the container will wipe the resources (covers, screenshots, etc.)

    "},{"location":"System-Setup/Unraid-Compose-Setup/#finish","title":"Finish","text":"

    Grab IP:Port from romm, and open tab in browser in http://IP:Port and it should take you to setup screen

    "},{"location":"System-Setup/Unraid-Setup-Guide/","title":"Unraid Setup Guide","text":""},{"location":"System-Setup/Unraid-Setup-Guide/#prerequisites","title":"Prerequisites","text":"

    Before getting started, install the Community Apps plugin for Unraid.

    "},{"location":"System-Setup/Unraid-Setup-Guide/#docker-network","title":"Docker network","text":"

    You'll want to create a custom bridge-type network for both containers to communicate with each other. This will prevent a number of common issues Unraid users tend to come across during setup. This can be done with the following command: docker network create romm, and you can verify it worked with docker network ls.

    "},{"location":"System-Setup/Unraid-Setup-Guide/#mariadb","title":"MariaDB","text":"

    MariaDB is required to run RomM, so install it from the plugin registry. Only the official and linuxserver versions are supported, but the official version is preferred.

    Now fill in all the environment variables; descriptions of the options and sensible defaults are listed in the example docker-compose.yml file.

    Warning

    The network type must be set to Custom: romm

    "},{"location":"System-Setup/Unraid-Setup-Guide/#installation","title":"Installation","text":"

    From the Unraid dashboard, click APPS in the navigation bar. In the search bar, search for romm, and install the app listed as \"OFFICIAL\". This one is maintained by our team and is the most up-to-date.

    "},{"location":"System-Setup/Unraid-Setup-Guide/#configuration","title":"Configuration","text":"

    Configure the required environment variables, ports and paths as per the example docker-compose.yml file.

    Warning

    The network type must also be set to Custom: romm

    Apply the changes, then head to the DOCKER tab. You should see both containers in a running state, and can access RomM using the IP:PORT of the container (highlighted below).

    Warning

    It's strongly recommended to backup the appdata folder (or mount it in a safe location) before updating, since tearing down the container will wipe the resources (covers, screenshots, etc.)

    "},{"location":"System-Setup/Unraid-Setup-Guide/#video-tutorial","title":"Video tutorial","text":"

    DemonWarriorTech has published How to Install RomM on Unraid (Beginner Friendly) on installing and running RomM on Unraid for Beginners with an in depth instructions and explanation of the software install and how to use it.

    AlienTech42 has published a great video on installing and running RomM on Unraid. While a bit out of date vis-a-vis install instructions, it's still very useful for general setup and debugging. Check it out!

    "},{"location":"System-Setup/Unraid-Setup-Guide/#unraid-community-support","title":"Unraid community support","text":"

    You can find a support thread in the unraid forums.

    "},{"location":"System-Setup/Unraid-Setup-Guide/#shout-outs","title":"Shout-outs","text":"

    We want to give a special shout-out to @Smurre95 and @sfumat0 for their help documenting this process, and working towards getting RomM listed in CA. \ud83e\udd1d

    "},{"location":"Tools/Igir-Collection-Manager/","title":"Igir Collection Manager","text":"

    Igir is a zero-setup ROM collection manager that sorts, filters, extracts or archives, patches, and reports on collections of any size on any OS. It can be used to rename your ROMs to match the RomM database, and to move them into a new directory structure.

    "},{"location":"Tools/Igir-Collection-Manager/#setup","title":"Setup","text":""},{"location":"Tools/Igir-Collection-Manager/#directory-structure","title":"Directory structure","text":"

    The directory structure is important for running the bulk ROM renaming script. Before running the bulk ROM renaming script, set up your directories as follows:

    .\n\u251c\u2500\u2500 dats/ # DAT files from no-intro.org\n\u251c\u2500\u2500 roms/ # Original ROM collection\n\u251c\u2500\u2500 roms-unverified/ # Working copy of ROMs\n\u2514\u2500\u2500 igir-romm-cleanup.sh\n
    "},{"location":"Tools/Igir-Collection-Manager/#initial-setup-steps","title":"Initial Setup Steps","text":"
    1. Create a working copy of your ROMs:

      cp -r roms/ roms-unverified/\n

      This provides a safe working environment and allows for easy script adjustment if needed.

    2. Download DAT Files:

      Extract the DAT files to your dats directory. You can optionally extract a subset of the .dat files into the directory instead.

    "},{"location":"Tools/Igir-Collection-Manager/#configuration","title":"Configuration","text":"

    Create the cleanup script igir-romm-cleanup.sh with the contents below:

    #!/usr/bin/env bash\nset -ou pipefail\ncd \"$(dirname \"${0}\")\"\n\nINPUT_DIR=roms-unverified\nOUTPUT_DIR=roms-verified\n\n# Documentation: https://igir.io/\n# Uses dat files: https://datomatic.no-intro.org/index.php?page=download&op=daily\ntime npx -y igir@latest \\\n  move \\\n  extract \\\n  report \\\n  test \\\n  -d dats/ \\\n  -i \"${INPUT_DIR}/\" \\\n  -o \"${OUTPUT_DIR}/{romm}/\" \\\n  --input-checksum-quick false \\\n  --input-checksum-min CRC32 \\\n  --input-checksum-max SHA256 \\\n  --only-retail\n

    Make the script executable:

    chmod a+x igir-romm-cleanup.sh\n
    "},{"location":"Tools/Igir-Collection-Manager/#usage","title":"Usage","text":""},{"location":"Tools/Igir-Collection-Manager/#run-the-script","title":"Run the script","text":"

    Run the script. It will generate a new output directory named roms-verified, moving the files from roms-unverified if its checksum matches any of the known checksums in the DAT files provided. Any ROMs not identified will remain in the roms-unverified directory.

    "},{"location":"Tools/Igir-Collection-Manager/#manually-move-over-remaining-files","title":"Manually move over remaining files","text":"

    The script may not identify all of the ROMs in your input directory. You can choose to migrate them over manually:

    npx -y igir@latest \\\n  move \\\n  -i roms-unverified/ \\\n  -o roms-verified/ \\\n  --dir-mirror\n

    This will move your ROMs from the input to the output directory, preserving the subdirectory structure. It also cleans up file extensions in the process.

    "},{"location":"Tools/Igir-Collection-Manager/#reorganize-multi-disc-games","title":"Reorganize multi-disc games","text":"

    The Igir script will move games that have multiple discs to separate folders. This can confuse RomM's game detection, and those games need to be reorganized into single folders with many discs.

    To do this enter your platform directory, such as ps or psx and run the following:

    ls -d *Disc* | while read dir; do\n  game=$(echo \"${dir}\" | sed -r 's/ \\(Disc [0-9]+\\)//')\n  mkdir -p \"${game}\"\n  mv \"${dir}\"/* \"${game}/\"\n  rm -rf \"${dir}\"\ndone\n

    This will find any directory with (Disc in the name and move the files into a new directory without the (Disc #) string. For example:

    Before:

    Final Fantasy VII (Disc 1) (USA)\nFinal Fantasy VII (Disc 2) (USA)\n

    Gets combined to:

    Final Fantasy VII (USA)\n
    "},{"location":"Troubleshooting/Authentication-Issues/","title":"Troubleshooting Authentication","text":""},{"location":"Troubleshooting/Authentication-Issues/#error-403-forbidden","title":"Error: 403 Forbidden","text":"

    When authentication is enabled, most endpoints will return a 403 Forbidden response if you're not authenticated, or if your sessions is in a broken state. The session key can be reset by clearing your cookies.

    CSRF protection is also enabled, which helps to mitigates CSRF attacks (useful if your instance is public). If you encounter a Forbidden (403) CSRF verification failed error, simply reloading your browser should force it to fetch a fresh CSRF cookie.

    "},{"location":"Troubleshooting/Authentication-Issues/#error-unable-to-login-csrf-token-verification-failed","title":"Error: Unable to login: CSRF token verification failed","text":"

    This error is known to happen on Chrome, but could happen in other browsers; manually clear your cookies (specifically one called csrftoken) and hard reload your browser window (CMD+SHIFT+R on macOS, CTRL+F5 on Windows).

    "},{"location":"Troubleshooting/Authentication-Issues/#error-400-bad-request-on-the-websocket-endpoint","title":"Error: 400 Bad Request on the Websocket endpoint","text":"

    If you're running RomM behind a reverse-proxy (Caddy, Nginx, etc.), ensure that Websockets are supported and enabled. This may vary depending on the reverse proxy solution being used. In the case of Nginx Proxy Manager, enable the \"Websockets Support\" toggle when editing the proxy host.

    "},{"location":"Troubleshooting/Kubernetes-Issues/","title":"Kubernetes Troubleshooting","text":""},{"location":"Troubleshooting/Kubernetes-Issues/#error-invalid-host-in-tcpinternal-ip8080-of-the-listen-directive-in-etcnginxconfddefaultconf7","title":"Error: invalid host in \"tcp://<internal ip>:8080\" of the \"listen\" directive in /etc/nginx/conf.d/default.conf:7","text":"

    By default, Kubernetes will grab information about the service object linked to a pod and inject it as an environment variable into the pod. In RomM, this leads to the pod attempting to bind to the service IP address, leading to the above fatal error.

    To resolve thes error, this default Kubernetes behaviour needs to be disabled by setting the enableServiceLinks value in the pod spec to false.

    apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: romm\n  namespace: romm\n  ...\nspec:\n  ...\n  template:\n    ...\n    spec:\n      enableServiceLinks: false\n      ...\n
    "},{"location":"Troubleshooting/Miscellaneous-Troubleshooting/","title":"Miscellaneous Troubleshooting","text":""},{"location":"Troubleshooting/Miscellaneous-Troubleshooting/#restarting-the-container-when-using-sqlite-drops-all-the-datarequires-a-full-re-scan","title":"Restarting the container when using SQLite drops all the data/requires a full re-scan","text":"

    Verify that the database is mapped to a persistent storage volume in your docker compose or Unraid template.

    \"/path/to/database:/romm/database\" # [Optional] Only needed if ROMM_DB_DRIVER=sqlite or not set\n
    "},{"location":"Troubleshooting/Miscellaneous-Troubleshooting/#error-could-not-get-twitch-auth-token-check-client_id-and-client_secret","title":"Error: Could not get twitch auth token: check client_id and client_secret","text":"

    This is likely due to mis-configured environment variables; verify that CLIENT_ID and CLIENT_SECRET are set correctly, and that both match the values in IGDB.

    "},{"location":"Troubleshooting/Miscellaneous-Troubleshooting/#how-to-view-romm-logs-to-assist-with-troubleshooting","title":"How to view RomM logs to assist with troubleshooting","text":"

    Each platform may have different logs, but check the stdout logs for docker. For example when using the recommended docker compose setup docker logs -f romm will display a continuous stream of the log. Most lines start with INFO, WARNING, or ERROR

    "},{"location":"Troubleshooting/Scanning-Issues/","title":"Troubleshooting Scanning","text":""},{"location":"Troubleshooting/Scanning-Issues/#scan-is-skipping-all-platformsends-instantly","title":"Scan is skipping all platforms/ends instantly","text":"

    There are a few common reasons why a scan may end instantly/without scanning platforms

    "},{"location":"Troubleshooting/Scanning-Issues/#roms-not-found-for-platform-x-check-romm-folder-structure","title":"ROMs not found for platform X, check romm folder structure","text":"

    This is the same issue as the one above, and can be quickly solved by verifying your folder structure. RomM expects a library with a folder named roms in it, for example:

    "},{"location":"Troubleshooting/Scanning-Issues/#scan-does-not-recognize-a-platform","title":"Scan does not recognize a platform","text":"

    When scanning the folders mounted in /library/roms, the scanner tries to match the folder name with the platform's slug in IGDB. If you notice that the scanner isn't detecting a platform, verify that the folder name matches the slug in the URL of the platform in IGDB. For example, the Nintendo 64DD has the URL https://www.igdb.com/platforms/64dd, so the folder should be named 64dd.

    "},{"location":"Troubleshooting/Scanning-Issues/#scan-times-out-after-4-hours","title":"Scan times out after ~4 hours","text":"

    The background scan task times out after 4 hours, which can happen if you have a very large library. The easiest work around is to keep running scans every 4 hours, without checking the \"Complete re-scan\" option. You can also change the timeout via environment variable SCAN_TIMEOUT.

    "},{"location":"Troubleshooting/Scanning-Issues/#scan-stops-before-finishing-a-platform","title":"Scan stops before finishing a platform","text":"

    Check the logs for RomM, you should find a line that looks like ERROR: [RomM][scan_handler][2025-04-12 11:48:55] that explains why the scanner stopped. This can often happen due to a corrupted file or a file the python zipfile library cannot handle, such as old DOS zip files with backslashes instead of forward slashes.

    "},{"location":"Troubleshooting/Scanning-Issues/#when-scanning-a-very-large-library-with-many-platforms-it-is-difficult-to-keep-track-of-which-systems-have-scanned-in","title":"When scanning a very large library with many platforms it is difficult to keep track of which systems have scanned in","text":"

    The easiest method is to check the logs via this command, which will list all the scanned platforms since the RomM container was started docker logs romm 2>/dev/null|egrep 'scan_handler.*Identified as.*\ud83c\udfae'

    Here is an example output:

    $ docker logs romm 2>/dev/null|egrep 'scan_handler.*Identified as.*\ud83c\udfae'\nINFO:     [RomM][scan_handler][2025-04-12 11:37:40]   Identified as PlayStation \ud83c\udfae\nINFO:     [RomM][scan_handler][2025-04-12 14:39:32]   Identified as DOS \ud83c\udfae\nINFO:     [RomM][scan_handler][2025-04-13 12:50:42]   Identified as WonderSwan \ud83c\udfae\n
    "},{"location":"Troubleshooting/Synology-Issues/","title":"Troubleshooting Synology","text":""},{"location":"Troubleshooting/Synology-Issues/#errno-13-access-denied","title":"ErrNo 13: Access Denied","text":"

    We have noticed recently a spate of access denied on Synology systems via Portainer or even docker manager. The ErrNo13 is directly related to Synology and it is a simple permission issue. To fix it please do the following:

    1. Make sure SSH is enabled on your Synology product. Refer to here if it is not Enable SSH
    2. Connect to SSH and login as your admin username and password (Same login used to login to DSM web page)
    3. Take a note on your user:group you can find this by typing ID when logged into SSH.
    4. Type the following commands in the SSH window.

    sudo chown -R user:group /path/to/library

    sudo chmod -R a=,a+rX,u+w,g+w /path/to/library

    sudo chown -R user:group /path/to/assets

    sudo chmod -R a=,a+rX,u+w,g+w /path/to/assets

    sudo chown -R user:group /path/to/config

    sudo chmod -R a=,a+rX,u+w,g+w /path/to/config

    You will find the relevant directories in your compose, this is basically the folders where you store your RomM information and we are just resetting permissions. Restart the containers and you should now have no issues scanning information in!

    Any issues please ask in the Discord.

    Thanks to Docker IDs - DrFrankenstein for the guidance from his blog.

    "},{"location":"Usage/Administration/","title":"Administration","text":"

    Clicking on your Profile icon from any screen opens the Administration Drawer. This drawer will look slightly different based on your role. The options available can include Profile, User Interface, Library Management, Administration, Server Stats, and About.

    "},{"location":"Usage/Administration/#profile","title":"Profile","text":"

    All users can access this screen. From here you can change your username, password, and email.

    Additionally, you can submit your RetroAchievements username and synchronize your achievements here.

    "},{"location":"Usage/Administration/#user-interface","title":"User Interface","text":"

    From here you can:

    "},{"location":"Usage/Administration/#library-management","title":"Library Management","text":"

    From this screen you can:

    "},{"location":"Usage/Administration/#administration","title":"Administration","text":"

    From this page you can manage users and check scheduled and manual tasks.

    "},{"location":"Usage/Administration/#server-stats","title":"Server Stats","text":"

    This area displays the number of platforms, games, saves, states, and screenshots on the server, as well as how much disk space this consumes. Platforms can be filtered here to show how much each platform contributes to total size and game count.

    "},{"location":"Usage/Administration/#about","title":"About","text":"

    This pop-up displays your RomM version with links to the community Discord, GitHub, and documentation.

    "},{"location":"Usage/LibraryManagement/","title":"Library Management","text":""},{"location":"Usage/LibraryManagement/#the-library-view","title":"The Library View","text":"

    The default library view shows a few ribbons: Recently Added, Continue Playing, Platforms, and Collections. Games and Platforms are presented as cards that can be interacted with.

    The menu bar is constantly visible and includes tools to Search, List Platforms, Manage Collections, Scan, go into Console Mode, and Upload content as well as access your administration panel.

    In all views, a grid icon is present in the upper right of the screen or container. This can be toggled to collapse or expand the container.

    "},{"location":"Usage/LibraryManagement/#game-and-platform-cards","title":"Game and Platform cards","text":"

    Platform cards can be clicked to go directly to the platform. A game card can be interacted with in several ways: putting your mouse over it allows you to download the game, play the game if the system is supported, or open a context menu giving you the option to manually match game information using a metadata agent, edit existing data, refresh the metadata, and add or remove the game from favourites or collections.

    Clicking a platform will take you to the platform view, while clicking a game will take you to the game view.

    "},{"location":"Usage/LibraryManagement/#filters","title":"Filters","text":"

    Filters are present on nearly every screen in RomM, allowing you to quickly drill down to see only the information relevant to your search.

    If you perform a search first, the listed filters will be taken from the metadata of all present games. For example, if you searched for the word \"Fox\", and then clicked filters and selected a Language, the list of languages available will be taken from the displayed games.

    "},{"location":"Usage/LibraryManagement/#toggles","title":"Toggles","text":"

    The filters that can be toggled include:

    Next there is a platform dropdown. This allows you to select a platform you want to restrict your view to showing.

    After this you can filter by metadata: Game Genre, Franchise, Collections, Company, Age Rating, Region, and Language. One additional filter exists after these: Status. This allows you to use the \"personal\" data tab on any game to track your progress of the game (never played, backlogged, complete, etc).

    "},{"location":"Usage/LibraryManagement/#the-menu-bar","title":"The Menu bar","text":"

    The menu bar is designed for quick access to the tools of your RomM server.

    "},{"location":"Usage/LibraryManagement/#search","title":"Search","text":"

    Simply typing text into the search bar will bring up game cards for each game that matches the query. To the left of the search bar are two icons: the view filters and the new collection button.

    "},{"location":"Usage/LibraryManagement/#list-platforms","title":"List Platforms","text":"

    The Platforms button opens a drawer listing all of the known platforms in RomM. Clicking on any of these will create a search that is limited to that platform.

    "},{"location":"Usage/LibraryManagement/#collections","title":"Collections","text":"

    The Collections button opens a drawer listing all of your manually created collections which is specific to each user, as well as your autogenerated collections created by RomM. Clicking a collection will take you to the collection view.

    "},{"location":"Usage/LibraryManagement/#scan","title":"Scan","text":"

    This is where you'll scan for new platforms and games. Metadata sources can be selected to determine which providers will be used to fetch metadata. Use the Platforms dropdown to restrict your scan to specific platforms.

    The Scan options dropdown allows you to choose a specific type of scan to perform:

    "},{"location":"Usage/LibraryManagement/#console","title":"Console","text":"

    This button will take you to a new full screen UI that's especially good for navigation with a controller.

    "},{"location":"Usage/LibraryManagement/#upload","title":"Upload","text":"

    This button allows you to upload games directly to RomM from the user interface. Simply select a platform and then either click to browse to a ROM or drag and drop it onto the interface.

    "},{"location":"Usage/LibraryManagement/#recently-added","title":"Recently Added","text":"

    After a scan is performed, the most recently added games can be found on this ribbon.

    "},{"location":"Usage/LibraryManagement/#continue-playing","title":"Continue Playing","text":"

    After a game has been played for any amount of time, it's added to this row. The context menu gains a new option for games located on this ribbon: remove from playing. This helps prevent the ribbon from being cluttered by games you wanted to test but do not plan on playing long term.

    "},{"location":"Usage/LibraryManagement/#platforms","title":"Platforms","text":"

    The list of platforms presented here will be matched by RomM by directory structure. See Supported Platforms page for more information about naming your directories.

    "},{"location":"Usage/LibraryManagement/#favourites-and-collections","title":"Favourites and Collections","text":"

    This ribbon contains all the games you've marked as favourites, and any collections you've created or that have been generated by RomM.

    "},{"location":"Usage/LibraryManagement/#platform-view","title":"Platform View","text":"

    The platform view shows all of the games for a specific platform. There is a button to show the platform drawer, the platform firmware, as well as the usual filter button.

    "},{"location":"Usage/LibraryManagement/#platform-drawer","title":"Platform Drawer","text":"

    The platform view drawer has a large icon representing the platform, along with its title.

    Below that is a button to upload ROMs and a button to initiate scans.

    Below that is a line showing how many metadata providers are being used for that platform.

    Next comes all the metadata for the platform itself: the name, folder name, category, generation, and so on.

    Following that are the platform settings, which consists of the style of cover used in the game cards for that platform.

    Finally, in the Danger Zone, is a Delete Platform button. This removes the platform from the database, it does NOT touch the files on your system. If you delete a platform in this way, scanning for new platforms will restore it, and all games will have to have their metadata re-matched.

    "},{"location":"Usage/LibraryManagement/#firmware","title":"Firmware","text":"

    Next to the platform drawer button is the firmware button. This allows you to review all of the firmware for that system, and upload firmware using the user interface.

    Uploading firmware will open a file browse dialog box. Simply select the BIOS file or files you wish to upload and click \"Upload\".

    "},{"location":"Usage/LibraryManagement/#collection-view","title":"Collection View","text":"

    The Collection View is similar to the Platform View. It has a Platform drawer next to the filters, much like how the Platform View has the Platform Drawer, but lacks the Firmware button.

    The Collection metadata will be shown, which includes a game count, who owns the collection, the privacy of the collection, and the ability to delete the collection.

    "},{"location":"Usage/LibraryManagement/#game-view","title":"Game View","text":"

    The game view is broken down into two distinct parts.

    The first container is the poster, with the usual download, play (if the system allows for playing in a web browser) and context menu as well as a new button: copy download link.

    The second container is the game tabs: Details, Game Data, and Personal tabs. These are containers for information about the game, how RomM sees the save data, and your personal notes. Additional tabs may be visible here depending on your configuration, including the Game Manual, data from How Long to Beat, screenshots, as well as related games. The Details tab includes metadata for the game. This will show where the data comes from, the platform and year of release, as well as the file information like regions and collections. This is the information that is used for filtering.

    The Game Data tab includes save files and save states, the ability to upload and download them, as well as delete them. This data is personal to the logged in user.

    Finally the Personal tab has check boxes denoting if a game is backlogged, being played, or if it should be hidden. User data such as rating, difficulty, % completed, and the status of the game can also be set here. RetroAchievements can be viewed from this tab for supported matched games.

    If How Long To Beat is enabled as a metadata provider, there will also be a tab here for viewing that data as well.

    "},{"location":"Usage/UserManagement/","title":"User Management","text":"

    The Administration panel contains the tools used to manage users on the server. The first user created will always be given the admin role.

    Users can manage their own game saves, save states, their profile icon, and the \"Personal\" data tab on games.

    "},{"location":"Usage/UserManagement/#adding-users","title":"Adding Users","text":"

    Adding a user is as simple as providing a username, password, email address, and selecting a role. Users can be added manually using the \"Add\" button or by inviting a user via link. When inviting a user, you only need to set a role; they will be prompted to complete the rest of the information.

    "},{"location":"Usage/UserManagement/#roles-explained","title":"Roles Explained","text":"

    Admin - The highest authority role. This grants full permission to do everything on the server.

    Editor - Can edit platforms and games (adding, removing, or scanning for new content) and make collections public.

    Viewer - The most restricted role. Can play games and interact with the Personal data tab.

    "},{"location":"Usage/UserManagement/#removing-users","title":"Removing Users","text":"

    Removing a user is as simple as clicking the red delete icon and confirming the operation.

    "}]} \ No newline at end of file