Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pre-launch/post-exit environment variables for wrapper script to detect game #5407

Closed
mtkennerly opened this issue Apr 8, 2024 · 15 comments · Fixed by #5408
Closed

Pre-launch/post-exit environment variables for wrapper script to detect game #5407

mtkennerly opened this issue Apr 8, 2024 · 15 comments · Fixed by #5408

Comments

@mtkennerly
Copy link

mtkennerly commented Apr 8, 2024

For context, I'm the author of Ludusavi. It has a feature to be used as a wrapper to back up your save data, like ludusavi wrap --name "Game Title" -- ./game --foo. To avoid writing out the title, it also supports --infer [steam|heroic], which will check for some environment variables in order to figure out which game is running.

I'd like to add support for --infer lutris, and I was wondering if you'd be open to adding some environment variables to support that. It would just need enough information so it can uniquely identify the game in the database and/or YAML files. Would LUTRIS_GAME_SLUG (table: games, column: slug) be sufficient, or would LUTRIS_GAME_ID (table: games, column: id) be better?

These were the closest I could find, but I don't think they cover this use case:

lutris/lutris/game.py

Lines 689 to 691 in 3866cf2

env["game_name"] = self.name # What is this used for??
env["GAMEID"] = proton.get_game_id(self)
env["STORE"] = self.get_store_name()

env["LUTRIS_GAME_UUID"] = str(uuid.uuid4())

@danieljohnson2
Copy link
Contributor

I do not think either of those will do. GAMEID is an Umu thing, not a Lutris ID. LUTRIS_GAME_UUID is a identifier of a single game execution, used to find processes to kill when you click 'Stop'.

I think you would want something like LUTRIS_GAME_ID, which would be the 'id' from the games table. That is the id that shows up in the output of lutris --list-games --json, and that gives the game's directory, name, slug, etc.

But I'm not sure this is right. I don't know what data you need to infer, and if it is in the json it might be nice to get it from just one game, not a dump of all of them. Or maybe just get what you need in an env-var- that'd be less likely to go wrong I think.

Anyway, 'id' is the unique ID for that table, and the slug is not unique. You can absolutely have two rows with the same slug; that might be two configurations of the same underlying game.

@mtkennerly
Copy link
Author

mtkennerly commented Apr 8, 2024

Thanks for the quick reply :)

But I'm not sure this is right. I don't know what data you need to infer

Ludusavi needs:

  • Title (we try to match this to an entry in Ludusavi's data set)
  • Install folder (to look for save data)
  • Wine prefix folder (to look for save data)

If wrapper scripts could have direct access to those pieces of information via environment variables, that would be the simplest solution for my use case.

That is the id that shows up in the output of lutris --list-games --json, and that gives the game's directory, name, slug, etc.

Right now, Ludusavi collects the info it needs from the YAML files, which lets it support some unusual cases like scanning a disk backup from another system, where the system running Ludusavi may not actually have Lutris.

It could certainly use the Lutris CLI in wrap mode, but there might be some complications with that:

  • If Ludusavi is installed via Flatpak but Lutris is a standalone copy, then $XDG_DATA_HOME won't have the user's normal Lutris config.
  • If you have multiple Lutris config folders (maybe another system's backup or because you're testing a snapshot build), Ludusavi would need to know which Lutris instance is active during wrap mode.

@strycore
Copy link
Member

strycore commented Apr 8, 2024

We've reached a point where cloud saves is the single most important feature left to implement in Lutris. While there is some preliminary code for handling saves in Lutris, it is very minimal and not usable yet.

Anyway, the plan is to support multiple backends to handle saves:

  • Integration with Lutris.net (saves are uploaded to the website, feature for Lutris Patreons)
  • Nextcloud App
  • Local filesystem
  • Managed by something else (Ludusavi, etc)

The Lutris API will make available some data on where to find saves. Like everywhere else in the project, we use the game slug as the identifier. We don't use the name ever because of games like Doom and Tomb Raider.

I would suggest against using pre-launch and post-exit scripts. I've never used those and don't plan to, pre-launch / post-exit is one of the most untested / here be dragons parts of Lutris. It is mostly used by people who don't want to make a pull request to add missing functionality to the client.

There will be (there already is, actually) parts of the code that handles game save sync. We hand over any data needed by Ludusavi at this stage. We could even send the location of the save files when we have that in our API.

Anyway, this is the perfect time to start working on this since it will be the focus of Lutris 0.5.18.

In any case the "id" field of the sqlite database should never be used and the LUTRIS_GAME_UUID even less, since it only exists for the duration of a single game launch.

@danieljohnson2
Copy link
Contributor

I've used pre/post launch scripts, though for compatibility not integration. Some games have weird requirements to get them to work. Sometimes you just have to joust with the dragons.

I'm prepping a PR to help these scripts, but I'll leave out the ID if you don't want it used. WINEPREFIX seems to be there already, right enough.

The name is also provided in the env-var "game_name", which is an odd name for an env-var, and it has a comment # What is this used for??- but that was there from the commit that introduced it. Weird. I'm tempted to rename it.

That leaves the game directory. I'll add GAME_DIRECTORY.

I suspect it is too late for this to make 0.5.17, though.

@danieljohnson2
Copy link
Contributor

OK, I've got the PR up. It is very simple. @mtkennerly, please give it a try.

Download this branch- no need to install it- and set up your scripts. You will have the WINEPREFIX, game_name and GAME_DIRECTORY env-vars, though only the third is new.

Does that work for you?

@mtkennerly
Copy link
Author

Does that work for you?

The changes look good to me, thanks! I'll try integrating them in Ludusavi, but there shouldn't be any issues.

(I do think it might be nice to add an env var for the slug, even just for logging purposes, but it's not necessary.)

We've reached a point where cloud saves is the single most important feature left to implement in Lutris.

There will be (there already is, actually) parts of the code that handles game save sync. We hand over any data needed by Ludusavi at this stage. We could even send the location of the save files when we have that in our API.

Let me know if I can help make any changes for Ludusavi to play nice with the eventual save sync API. Ludusavi gets data from PCGamingWiki, which does have a field to map games to Lutris slugs, so it might end up being useful to start tracking that in the Ludusavi manifest.

@danieljohnson2
Copy link
Contributor

Looks like @strycore took the PR, but he does not seem to want env-vars added without a clear purpose, so I won't add the slug without a clear use for it. I can't imagine you have our slugs in your database that you could look up.

@strycore
Copy link
Member

strycore commented Apr 9, 2024

the previous "game_name" env var didn't have a clear purpose. I have kept it but renamed it to GAME_NAME so the current users of "game_name" would show up (hopefully). Still, using the game name instead of the slug isn't ideal because of Doom, Prince of Persia and Tomb Raider. I know I'm comparing DOS games with Windows games but Lutris isn't limited to Windows games.

We also aim to sync save states and emulator memory cards. Our save backup system will depend a lot on the runner used. Most of the runners will be pretty straightforward to implement, what we need is metadata for DOS/Linux/Windows games

@mtkennerly
Copy link
Author

what we need is metadata for DOS/Linux/Windows games

If you'd like to try using the Ludusavi manifest for that data, I can start integrating Lutris slugs from PCGamingWiki's Infobox game template. Just let me know if there's any interest.

@danieljohnson2
Copy link
Contributor

I'm torn. If @strycore wasn't clearly against superfluous environment variables, I'd add GAME_SLUG- it seems easy and safe. And I see now that PCGamingWiki has our slugs on file, so there is some database out there that has them.

But there's no database anybody actually wants to use in a pre-launch script (or anything like that), and you don't have them or use them yourself. So this is all purely speculative.

That does not seem enough to justify what could well be an env-var that nobody ever uses.

@strycore
Copy link
Member

@strycore wasn't clearly against superfluous environment variables,

I'm against lower cased environment variables that appear out of nowhere, that have been asked by no one and confuse everyone.

You're somehow fixating on that and slowing your development down by creating non existent obstacles.

If the slug is needed by Ludusavi to function properly then we add the slug, there's no need to go on wild roundabout fanfics about it. Ideally, we add a note in the code that tells our future selves who is consuming this env var and why.

@strycore
Copy link
Member

If you'd like to try using the Ludusavi manifest for that data, I can start integrating Lutris slugs from PCGamingWiki's Infobox game template. Just let me know if there's any interest.

That would be a good start. It seems to me that PC gaming wiki only provides a single path for saves. We plan to have a more subtle system that can differentiate between configs, saves, log, screenshots, etc.

Maybe we can do an initial sync from PGW and use the Lutris API to give save info since we'll build more complete data over time.

@mtkennerly
Copy link
Author

It seems to me that PC gaming wiki only provides a single path for saves.

It can show up to 5 paths per platform per game (5 is just an arbitrary limit in the wiki template). It does distinguish saves and config, but not the other kinds you mentioned. Here's an example with multiple paths for a platform:

https://www.pcgamingwiki.com/wiki/Celeste#Game_data

@danieljohnson2
Copy link
Contributor

Welp, not torn anymore.

@mtkennerly
Copy link
Author

mtkennerly commented Apr 20, 2024

@strycore Lutris slugs are now being tracked in the Ludusavi manifest. I still need to do a full refresh to scrape all of them, but I did an initial scrape of 450 articles, which found 123 with slugs.

(Let me know if there's a better place to discuss this.)

Edit: Full refresh is done. I forgot about #57 - I'll post some info there.

@mtkennerly mtkennerly mentioned this issue Apr 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants