Skip to content

Conversation

unbelievableflavour
Copy link

@unbelievableflavour unbelievableflavour commented Aug 12, 2025

This feature adds support for custom JSON-based game libraries to Heroic Games Launcher. You can now add games from any source by providing JSON configuration files that describe your games, their installation tasks, and launch information.

This would allow us to make custom repos of online (and local) game installs that are not available on game platforms like Steam and GOG.

Example JSON:

{
  "name": "Freeware Games",
  "description": "A collection of freeware games from the internet",
  "games": [
    {
      "app_name": "unreal_tournament",
      "title": "Unreal Tournament",
      "executable": "Unreal Tournament/System/UnrealTournament.exe",
      "description": "Unreal Tournament is a first-person arena shooter video game developed by Epic Games and Digital Extremes. The original Unreal Tournament began as a mod for Unreal, but soon developed a life of its own. This Game of the Year Edition includes additional content and improvements.",
      "platform": "windows",
      "version": "1.0.0",
      "install_tasks": [
        { "type": "download", "url": "https://archive.org/download/unreal-tournament-complete/Unreal%20Tournament.zip" },
        { "type": "extract", "source": "Unreal%20Tournament.zip" }
      ],
      "launch_options": [
        { "type": "altExe", "name": "Unreal Editor", "executable": "Unreal Tournament/System/UnrealEd.exe" }
      ]
    },
    {
      "app_name": "rubber_ninjas_demo",
      "title": "Rubber Ninjas (Demo)",
      "executable": "Rubber Ninjas Demo.exe",
      "platform": "windows",
      "version": "1.05 (demo)",
      "art_cover": "https://rubberninjas.com/screens/9.jpg",
      "art_square": "https://rubberninjas.com/screens/9.jpg",
      "install_tasks": [
        { "type": "download", "url": "https://rubberninjas.com/Rubber_Ninjas_Demo_Setup.exe" },
        { "type": "run", "executable": "Rubber_Ninjas_Demo_Setup.exe", "args": ["/VERYSILENT", "/DIR={gameFolder}"] }
      ],
      "uninstall_tasks": [
        { "type": "run", "executable": "unins000.exe" }
      ]
    },
    {
      "app_name": "soldat",
      "title": "Soldat",
      "executable": "soldat.exe",
      "platform": "windows",
      "version": "1.7.1.1",
      "install_tasks": [
        { "type": "download", "url": "https://soldat.pl/down.php?id=107&mirror=https%3A%2F%2Fstatic.soldat.pl%2Fdownloads%2Fsoldat1711.zip&lang=en" },
        { "type": "extract", "source": "soldat1711.zip" },
        { "type": "run", "executable": "soldat1711.exe", "args": ["/VERYSILENT", "/DIR={gameFolder}"] }
      ]
    },
    {
      "app_name": "counter_strike_2d",
      "title": "CS2D",
      "executable": "Counter Strike 2D [Portable]/CounterStrike2D.exe",
      "platform": "windows",
      "version": "1.0.3",
      "install_tasks": [
        { "type": "download", "url": "https://www.unrealsoftware.de/get.php?get=cs2d_1016_win.zip&p=1&cid=1245" },
        { "type": "extract", "source": "cs2d_1016_win.zip" }
      ]
    },
    {
      "app_name": "grid_wars",
      "title": "Grid Wars",
      "executable": "GridWars.exe",
      "platform": "windows",
      "version": "5.3",
      "install_tasks": [
        { "type": "download", "url": "https://archive.org/download/grid-wars_202311/GridWars.zip" },
        { "type": "extract", "source": "GridWars.zip" }
      ]
    },
    {
      "app_name": "cave_story",
      "title": "Cave Story",
      "executable": "CaveStory/Doukutsu.exe",
      "platform": "windows",
      "version": "1.0.0",
      "install_tasks": [
        { "type": "download", "url": "https://www.cavestory.org/downloads/cavestoryen.zip" },
        { "type": "extract", "source": "cavestoryen.zip" }
      ],
      "launch_options": [
        { "type": "altExe", "name": "Org View", "executable": "CaveStory/OrgView.exe" },
        { "type": "altExe", "name": "Configuration Tool", "executable": "CaveStory/DoConfig.exe" }
      ]
    },
    {
      "app_name": "celeste_64",
      "title": "Celeste 64: Fragments of the Mountain",
      "executable": "Celeste64.exe",
      "platform": "windows",
      "version": "1.1.1",
      "install_tasks": [
        { "type": "download", "url": "https://github.com/EXOK/Celeste64/releases/download/v1.1.1/Celeste64-v1.1.1-Windows-x64.zip" },
        { "type": "extract", "source": "Celeste64-v1.1.1-Windows-x64.zip" }
      ]
    },
    {
      "app_name": "wolfenstein_enemy_territory",
      "title": "Wolfenstein: Enemy Territory",
      "executable": "et.exe",
      "platform": "windows",
      "version": "1.0.1",
      "install_tasks": [
        { "type": "download", "url": "https://cdn.splashdamage.com/downloads/games/wet/WolfET_2_60b_custom.exe" },
        { "type": "run", "executable": "WolfET_2_60b_custom.exe", "args": ["/S", "/D={gameFolder}"] }
      ],
      "uninstall_tasks": [
        { "type": "run", "executable": "uninstall.exe" }
      ],
      "launch_options": [
        { "type": "altExe", "name": "Dedicated Server", "executable": "etded.exe" }
      ]
    },
    {
      "app_name": "rayman_redemption",
      "title": "Rayman Redemption",
      "executable": "Rayman Redemption.exe",
      "platform": "windows",
      "version": "1.0.3",
      "install_tasks": [
        { "type": "download", "url": "https://archive.org/download/raymanredemption/raymanredemption.zip" },
        { "type": "extract", "source": "raymanredemption.zip" }
      ],
      "uninstall_tasks": [],
      "launch_options": []
    }
  ]
}

A more thorough explanation on how it works can be found in the doc file I've included in the PR.
https://github.com/unbelievableflavour/HeroicGamesLauncher/blob/custom-libraries/doc/custom_libraries.md


Use the following Checklist if you have changed something on the Backend or Frontend:

  • Tested the feature and it's working on a current and clean install.
  • Tested the main App features and they are still working on a current and clean install. (Login, Install, Play, Uninstall, Move games, etc.)
  • Created / Updated Tests (If necessary)
  • Created / Updated documentation (If necessary)

@Heroic-Games-Launcher Heroic-Games-Launcher locked and limited conversation to collaborators Aug 12, 2025
@Heroic-Games-Launcher Heroic-Games-Launcher unlocked this conversation Aug 12, 2025
@flavioislima flavioislima added the pr:ready-for-review Feature-complete, ready for the grind! :P label Aug 13, 2025
@flavioislima flavioislima requested review from a team, CommandMC, arielj and flavioislima and removed request for a team August 13, 2025 09:34
@unbelievableflavour
Copy link
Author

Sorry for all the extra commits everyone. Found a couple more relatively small issues that I wanted to fix which would make the implementation a bit cleaner. Hope you guys weren't in the middle of a review yet.

@unbelievableflavour unbelievableflavour changed the title Added Custom libraries runner [Feat] Added Custom libraries runner Aug 20, 2025
Copy link
Collaborator

@CommandMC CommandMC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the idea of making it easy to add custom runners is great, however I'm not sure I like the approach this PR took. In my mind, a runner provides games from the same general source that work the same way

What I would like better (and have worked on in the past): Heroic loads "runner plugins" from a directory in its config folder. Every runner plugin is a JavaScript file exporting an object of a certain shape (your work in #4897 comes to mind there, although I'd like to simplify the library/game managers a lot first). They also get a "context" (somehow, perhaps in an init method?), containing common functions (like downloading or extracting files) they can then use as they wish, similar to the "install tasks" introduced here

With that model, you may create one "runner plugin" for every game you've described in your PR description, with a lot more flexibility (in this PR, the second a game install/launch/etc deviates from the described schema even slightly, you'd need to edit Heroic's source to add new handling, while plugins can be updated independently). The downside there is of course more boilerplate (especially with the current shape of game & library managers; as mentioned, I'd like to slim those down first before a feature like this could be implemented)

Anyways, I'm not really sure where I'm going here. I guess we just both had the same idea at the same time? Let me know what you think of my approach, perhaps we can find something in the middle of both solutions?

On a somewhat related note: As you can tell by this rant, I obviously had an idea like this in mind before already, and have actually worked on code for it (albeit on a local branch). To avoid duplicate/wasted work, would you mind contacting us (ideally on Discord, although an issue in this repo would also be fine) if you have plans for more changes like this, just to allow discussion before the actual code writing starts?

@unbelievableflavour
Copy link
Author

That's ok @CommandMC :)

I like your idea of runner plugins, although that would mean you would need more technical knowledge about heroic to create those, while my idea of this implementation was: "Anyone could create a library with only some JSON knowledge and a small readme to understand how to add games".

You could ofcourse just do a simple task system in a javascript file like I did in my implementation as well. And then if people would want something more complicated they could create use a "custom task" for more complex stuff. That way you would have the best of both worlds.

  • Easier to get into runner plugin creation.
  • If you want something more flexible, then it's available.

Feel free to grab any code from this PR that would fit the need for the runner plugin implementation. I'm just happy to help out :) love the project. Also, I'm already in the Discord. Just not really active there but if you wanna have a chat just ping me. Always up for a chat about this subject, it would be cool to have any similar to this in Heroic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:ready-for-review Feature-complete, ready for the grind! :P

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants