sonic2kk / steamtinkerlaunch

Linux wrapper tool for use with the Steam client for custom launch options and 3rd party programs
GNU General Public License v3.0
2.12k stars 71 forks source link

Feature Request: More Custom Command Control #625

Closed sonic2kk closed 3 months ago

sonic2kk commented 1 year ago

System Information

Feature Description

Background

I had an idea today while working through #624. That feature request was to add support for a specific mod manager to make setup easier. As it turns out, that mod manager pretty much only needs a winetrick or few. But because of how mod managers work, each game's prefix would need that winetrick. This got me thinking about ways to drastically improve and change how custom commands are handled with STL.

Problem

Some custom commands such as those related to modding, require tweaks and winetricks to get working. A user is very much capable of doing this with STL with its Winetricks menu, but for standalone executable programs that need to be selected on a per-game basis, this can get really tiresome. Having to go in and choose the winetrick each time, plus a user might forget if it's been a while!

There is also the case where a user might want a custom program installed to a specific prefix, either with or without Winetricks, unrelated to the current game's prefix. Say Cheat Engine for example - A user might want to download and install Cheat Engine once, into one prefix, and set that as a custom program for each game. Well as far as I know currently they can't choose a custom prefix for custom commands, and they'll have to remember where the Cheat Engine executable is for each game and set it (or check the config files with a text editor), and so on. You get the idea, this isn't ideal (and also not exclusive to Cheat Engine - Just a relevant example like HMM!)

The problem basically boils down to a lot of manual effort on the user's behalf when they want to set up a custom program for use with STL. In fairness, they could write a script that runs the application in the specific prefix, but that's not super user friendly :-) Having STL do some of the heavy lifting here would really help imo.

Enter: Overhauled Custom Commands

This feature request would solve the concerns I and others had around #618, and would also help solve #624. The idea I had to resolve of this is basically as follows:

Custom Command Management Menu

This would be a new menu where a user can manage a list of custom commands/executables that they create and configure. Initially it would be blank, but there would be some buttons along the bottom: "Back" "Edit", "Delete", "Duplicate" and "Add". When a user clicks add, they'll get a dialog asking them to enter information about the custom executable, similar to the "Add Non-Steam Game" dialog. This would add a custom command with a set configuration that can be accessed globally for each game.

For example they could add a CheatEngine custom command with a bunch of parameters, then for each game they can go into the Game Menu and see a dropdown where they can access a custom command for every game. That way, per game, they only have to select "Cheat Engine". They can also choose where the Cheat Engine prefix is stored and configure other options described below.

A custom executable would need various options, and when "Add" is clicked a dialog would open asking a user to enter that information. This dialog will be very similar to the "Add Non-Steam Game" dialog in terms of basic layout, and have options along the bottom with "Add" or "Cancel". Below are a list of fields I had in mind:

This expands upon the functionality in the Game Menu by letting a user choose a custom prefix, a custom Proton version, and custom Winetricks.

Let me explain the Winetricks idea. Some custom programs need some Winetricks. To use a real world example, HedgeModManager, a mod manager for several Sonic the Hedgehog games. HedgeModManager (or HMM for short) is a standalone executable and with dotnet48 you can run it in any game's prefix. This is crucial because this improves mod compatibility as HMM can run in the Sonic game's prefix! The problem arises when a user wants to use this with several other Sonic games. They'll need to install dotnet48 for every game's prefix before they can use the program!

With the approach described above, a user could simply add "HedgeModManager" as a custom command in the menu I described above, and add dotnet48 in the Winetricks box. Then, each time a game tries to run this custom command, if any of the listed winetricks are missing, STL will attempt to install them for that prefix. For a program that only needs dotnet48 that's probably not a big deal, but it's easy to envision a scenario where four or five or more Winetricks could be needed! Having this taken care of would be a huge help in my opinion. Of course a user is expected to know what their custom program needs to run, but once they know, STL can do the tinkering for them!

If a user later decides they need to edit a custom program's options, they can click on an item in the custom command list I described and choose the "Edit" button, which will open a dialog identical to the one above but it will be populated with their custom command information so they can edit it.

Storing Configurations

I'm not an expert so this might not be possible or the idea might need some tweaking, but in my head I envision something like this:

The SteamTinkerLaunch config folder gets a new folder: $HOME/.config/steamtinkerlaunch/customcmds/ and under here, we have some kind of file, probably a .conf file for convention's sake. And the name of this file will match the name of the custom command name provided, or perhaps a custom generated ID/incremented ID based on the last ID, or both with aliases like we do for game configs with title and id folders.

The file might look something like this:

# Half-Life 2: Episode Three.conf
ICON="/home/gaben/secret/hl3/hl3_logo_20230104.bmp"
NAME="Half-Life 2: Episode Three"
CMDPATH="/mnt/valve/secret/hl3/hl3.exe"
PREARGS="super-encrypt"
POSTARGS="--2008-alpha"
WINEPREFIX="/mnt/valve/secret/hl3/pfx"
PROTONVER="/home/gaben/.local/share/Steam/compatibilitytools.d/Proton 8.0-11"
WINETRICKS="xact,quartz,wmp11"

It would be nice if somewhere, there was a way to store which games were using it, but this seems overkill and might be complicated to implement, so not very important. This file is used to store the custom command data, and is also used to display and track the information in the menus I described above (the custom command list and the "edit custom command").

User-Created Configuration Templates

Using the configuration format I described above opens the possibility for user-created preset configurations! Let's say there's a popular tool, we'll go again with HMM. Well, to get it running on different systems, the only thing that will change is the path to the executable. The proposed system would allow users to copy these config files between installs or share them online, then they can download them and edit them to have the correct paths for their system - Either with a text editor or from the STL Yad frontend - Keeping in line with virtually all of SteamTinkerLaunch's configuration!

We could even have a section on the wiki with a list of common configuration templates that users can download. Users could submit them on the issue tracker or add it to the wiki themselves.

To me at least, this sounds super cool!

How Does This Tie Into The Game Menu?

Once a user has added their custom commands as described above, they can go into the Game Menu and it'll look a little different.

First off, keep the "Use custom command" option. This is nice to toggle on and off during testing!

Second, the "Custom command" field is going to change slightly. It would be a dropdown which by default has "None" (or "none" or "(none)" or whatever fits best). But when the user clicks it, the dropdown would contain all of the custom commands they have added. It would display "None" and under that would be all their custom commands, then there would be a separator and an "Other..." option where they can select a custom executable.

image

This allows for keeping of the existing functionality if a user just wants to load a program once.

On that note, the other options for custom command args, fork/only custom command, etc, can all stay because they're useful for choosing "Other" custom commands that a user may not want or need to add as an entry in the custom commands list.

However, "custom command arguments" should be ignored when a user has selected a command from the custom command list.

But I'm not totally sure how to handle this. There are cases where a custom command might need arguments for one game, but might not need them for other games. As a result, maybe the prepend/append custom command arguments should be in the Game Menu and not in the custom command's configuration file like I described above. I'm not sure on this one honestly! Maybe having it in the Game Menu gives the greatest flexibility.

The other options for fork/only custom command, wait custom command etc are virtually useless imo to configure per-custom program, but very useful to configure per game. A user might want the same custom program to launch instead of their game in one instance but might want it to launch with their game in another. Or they might want to switch between these choices for testing.

What's the tl;dr?

Add a menu where a user can add, edit and delete custom commands that can be shared across all games. These can be selected from a dropdown on the Game Menu.

Each custom command can have its own configuration, like what prefix to run in, and any relevant Winetricks, etc etc. Particularly for the Winetricks, when a user selects this custom command and presses "Play", the entered Winetricks will be installed into each prefix if they aren't installed there already. That way custom commands that need a bunch of Winetricks can have them easily installed each time without a user having to remember what Winetricks are needed, and installing it themselves.

Considerations

I do have a few concerns about how this would be implemented.

This is just what I can think of right now. There could be other things I'm failing to consider or don't know about that could cause big problems!

Notes

This is not urgent, but I had the idea fresh in my head today and made a bunch of notes. I wanted to get a fleshed out proposal for this with as much detail as possible up as an issue while it was in my head. Since other things are in the pipeline for STL, this should absolutely wait until those are done.

I'd gladly make an attempt at this myself but I have other projects I'm working on (including a couple of other ideas for STL), plus it might take me a while to implement something like this - actually, my experience in actual Bash scripting almost entirely begins and ends with my contributions to SteamTinkerLaunch starting in January this year!

Over the weekend I will try and see about making a few UI mockups in Yad to help illustrate how I envision this looking. Reading a whole bunch of text can be really tiring and confusing, so visually showing my ideas might help. At the time of writing I just don't have the time sadly.


Okay, that was long. I hope it at least sort of made sense. Maybe this is way too complicated to ever add, but I hope not. And of course just in case it comes across the wrong way: None of this is a demand or anything like that. I gave as many details as I could about the idea in my head in the hopes of illustrating why this would be a useful feature and worth implementing. And of course, having all these details can help with implementation - For anyone that might decide to pick it up.

If anything is unclear please feel free to ask. And of course feel free to leave comments about what might/might not be possible on a technical level for this. We can get a discussion going :smile:

Thanks!

KBouder commented 1 year ago

We could even have a section on the wiki with a list of common configuration templates that users can download. Users could submit them on the issue tracker or add it to the wiki themselves.

This would be nice. Not sure how easily this could be done, but having a Community Profile browser within STL where users can download and apply custom configurations straight through STL would be a nice addition as well.

frostworx commented 1 year ago

yeah this is close to the rough idea I presented yesterday here

Not saying that I will add it (in the near future), but might be worth to discuss at least. If there is broader interest, it would make sense to open a separate issue for further brainstorming.

So, let's simply use this issue to list target features. Needless to say this is a pretty huge task and requires lots of time, carefulness and testing

KBouder commented 1 year ago

Yeah, I saw that shortly after I typed that. I'm curious if tackling this first would in any way be beneficial to the MO2 rewrite.

sonic2kk commented 1 year ago

yeah this is close to the rough idea I presented yesterday https://github.com/frostworx/steamtinkerlaunch/issues/618#issuecomment-1270227778

Oops, I actually did see that comment but I guess the pieces didn't click in my head. Super sorry, I wasn't trying to take your idea or anything! Maybe it subconsciously played on my mind and that's why I thought about posting this.

Needless to say this is a pretty huge task and requires lots of time, carefulness and testing

Absolutely, and I hoped to get that across in some way in that post (and you said as much in your comment on the other issue). Of course it doesn't need to happen anytime soon either, and hopefully as mentioned this can serve as a checklist of sorts to work through if/when this idea gets tackled. And if anything doesn't make sense to implement or the implementation needs to change, that can all be discussed :-)

frostworx commented 1 year ago

No worries, everything is fine :) We should definitely take our time on gathering ideas and thoughts for a clear preplanned structure before even starting to write anything. I'm sure this will be a great feature whenever it is done. (might even be an opportunity to revive the old tweaks idea - we'll see)

sonic2kk commented 1 year ago

While fiddling around with custom commands earlier, I thought it would be nice if we could launch a custom command without closing STL. I was actually testing around HedgeModManager (no update on getting it to work on my end yet...) and having to keep re-launching STL each time during testing was a little bit of a pain.

Not even sure if this is possible or if there are other complications around it, but it would be nice if part of this custom command overhaul included being able to launch custom commands without closing STL. Or maybe even launching games without closing STL too? :sweat_smile:

Launching games while keeping STL opens means you can launch with tweaks for testing, and if something goes horribly wrong, or if there's a problem with a flavour of Proton you're trying out, you can quickly go back to the STL menu.

Maybe the options for running custom commands/games with STL open could also be a tray icon option? Though if it was somewhere else in the menus that would be very handy (Plasma Wayland can be temperamental with tray icons).

Of course this is just a rough idea. The best way to go about the "UX" for this is definitely something to tackle :smiley:

KBouder commented 1 year ago

That sounds very convenient, especially since with HMM, certain mods need to be loaded before others, and it isn't entirely clear what order they need to be in until you launch the game and it yells at you.

frostworx commented 1 year ago

thanks for the suggestion. Should be doable, and probably relatively easy to implement. Let's add it as a possible feature

just "Added option to keep the game open after the game closed" in this commit in the mo2-overhaul branch.

BrandonKingM commented 1 year ago

Is there any way to allow for the custom command to have different settings than the main game? Mass Effect Legendary Edition for example doesn't work with WineD3D, but the only way to use the ME3Tweaks Mod Manager is with WineD3D. I use the mod manager as a custom command with STL. If this isn't something that can be done, that's fine, its more a quality of life thing to usably inject it rather than have to do use custom command only.

sonic2kk commented 1 year ago

Is there any way to allow for the custom command to have different settings than the main game?

Not currently, though this feature request would implement it -- But not for the example that you have given. This example, as far as I know, will likely never be possible under Wine as there is no way to know which process is the mod manager and which is the game (i.e. when it knows it's the game, turn off PROTON_USE_WINED3D=1).

There is also no way currently to enable/disable environment variables at runtime, for Wine/Proton in general and not just with STL. In the case of something like a mod manager, since the mod manager itself is the only thing started as a Wine/Proton process, there is no way to pass Linux environment variables to an executable/command that gets ran by that already started Wine process.


With the example of ME3Tweaks, afaik you have to launch the game with that mod manager. There wouldn't be a way to SteamTinkerLaunch, or any program really, to differentiate between a custom program and the actual game you want to run.

For Wine especially I don't think this can be done, as the environment variable applies to that whole Wine process and not just that program, and I don't think flags can be enabled/disabled at runtime. You could probably have two separate Wine processes, one with PROTON_USE_WINED3D and one without, but that doesn't help this case as there's no way to get something like METweaks to use a separate process, it uses the same wineserver.


More generically it could be possible with the idea of this proposal, where you have much more granular control over custom programs. If the game and program were running separately, that is if you were running a custom program and the game as separate programs, it could certainly be done.

As an example, say you have some custom program that you start forked with a 300 second (5 minute) delay from the main game. This program might directly alter some config files but the game doesn't need to be launched from this program. This scenario would work. The custom program would be started as a separate Wine process with a separate launch command, maybe something like PROTON_USE_WINED3D=1 /path/to/proton run /path/to/program.exe. Then the game would be started later on after the 300 second delay with an entirely separate command something like /path/to/proton waitforexitandrun /path/to/game.exe.


Hope that makes sense on why this is not really feasible in your mod manager instance, it's a generic Wine "limitation" in that you can't really differentiate programs like this. That's not how Wine works. They need to run as separate processes. In more general terms though, if the game and custom program are started separately as separate Proton processes with separate commands to run them, then it is certainly possible to give these commands different environment variables, but that is not implemented in SteamTinkerLaunch yet.