How do I find the appid for a non-steam game on Steam
Solution 1:
Steam uses two different ids used to load art for non-steam shortcuts.
You can ignore the Big Picture specific logic and set the icon as your desired Big Picture art but that icon will also be used in Steam desktop client.
Steam Desktop
steamgrid figured out how to get a normal shortcut id. They describe the solution as "crc32(exe + appname) + "02000000"
, using IEEE standard polynomials" and using exe
and appname
from shortcuts.vdf.
For some reason, steamgrid refers it as the LegacyID, but this is the
format for art for steam's redesigned client. This id seems to be unrelated to
the desktop shortcut id (which is also used in screenshots.vdf) and unrelated
to images in Big Picture mode (which uses the icon
field in shortcuts.vdf).
UWPHook as a C# implementation to find the id and separate code for the paths.
import binascii
def get_steam_shortcut_id(exe, appname):
"""Get id for non-steam shortcut.
get_steam_shortcut_id(str, str) -> int
"""
grid = Path(f"{steam_path}/userdata/{steamid}/config/grid")
unique_id = ''.join([exe, appname])
id_int = binascii.crc32(str.encode(unique_id)) | 0x80000000
return id_int
Big Picture
scottrice/Ice steamgrid figured out how to get a Big Picture shortcut id. They explain:
Calculates the filename for a given shortcut. This filename is a 64bit integer, where the first 32bits are a CRC32 based off of the name and target (with the added condition that the first bit is always high), and the last 32bits are 0x02000000.
The implementation looks roughly like this (requires pycrc):
# Copyright (c) 2012-2013, 2013 Scott Rice
# All rights reserved. MIT License
import pycrc.algorithms as crc
def get_bigpicture_shortcut_id(exe, appname):
algorithm = crc.Crc(width = 32, poly = 0x04C11DB7, reflect_in = True, xor_in = 0xffffffff, reflect_out = True, xor_out = 0xffffffff)
input_string = ''.join([exe,appname])
top_32 = algorithm.bit_by_bit(input_string) | 0x80000000
full_64 = (top_32 << 32) | 0x02000000
return str(full_64)
See the original for more details/comments.
You can see that this is very similar to the normal shortcut id except it has some extra lower bits.
Bringing it Together
We can put it all together to get the locations for all the art like so:
from pathlib import Path
import binascii
def get_steam_shortcut_id(exe, appname):
"""Get id for non-steam shortcut.
get_steam_shortcut_id(str, str) -> str
"""
unique_id = ''.join([exe, appname])
id_int = binascii.crc32(str.encode(unique_id)) | 0x80000000
return id_int
def get_grid_art_destinations(steam_path, steamid, exe, appname):
"""Get filepaths for the grid images for the input shortcut.
get_grid_art_destinations(str, str, str, str) -> dict[str,Path]
"""
grid = Path(f"{steam_path}/userdata/{steamid}/config/grid")
shortcut = get_steam_shortcut_id(exe, appname)
bp_shortcut = (shortcut << 32) | 0x02000000
return {
'boxart': grid / f"{shortcut}p.jpg",
'hero': grid / f"{shortcut}_hero.jpg",
'logo': grid / f"{shortcut}_logo.png",
'10foot': grid / f"{bp_shortcut}.png",
}
import pprint
pprint.pprint(get_grid_art_destinations("C:/Program Files (x86)/Steam", '00000000', 'c:\\libraries\\itch\\baba\\Baba Is You\\Baba Is You.exe','Baba Is You'))
Here's a complete python implementation.