Skip to content

GameList: Add option to download all game icons#3655

Merged
stenzek merged 3 commits intostenzek:masterfrom
mariobob:download-game-icons
Dec 6, 2025
Merged

GameList: Add option to download all game icons#3655
stenzek merged 3 commits intostenzek:masterfrom
mariobob:download-game-icons

Conversation

@mariobob
Copy link
Contributor

@mariobob mariobob commented Dec 3, 2025

Added new functionality to downloads game icons from RetroAchievements for all games in the library missing icons, without needing to open each game individually. The functionality is attached to the existing option "Refresh Achievement Progress" in the View menu.

When triggered, a progress bar displays the batch download status:

image

Background

When a game is opened, DuckStation automatically downloads its icon from RetroAchievements and caches it. However, for users with large libraries, this means icons only appear after each game has been launched at least once.

Changes

  • Added Achievements::DownloadGameIcons() which uses the rc_api_fetch_game_titles API to batch-fetch badge information for all games with achievement data, then downloads missing icons
  • Added new menu action in View -> "Download All Game Icons"

@JukePlz
Copy link
Contributor

JukePlz commented Dec 3, 2025

Wouldn't a better implementation be to do this when the user calls "Refresh Achievement Progress" from View menu?

Maybe it's not as obvious, but I think it's justified by less UI pollution.

Would it affect the task speed significantly for large libraries?

@mariobob
Copy link
Contributor Author

mariobob commented Dec 4, 2025

@JukePlz Sure, that would cut down on UI pollution. I initially created it in a separate option to prevent it from being intrusive to the user. But on the other hand, the user can just press Cancel to abort the icon-downloading operation.

For a library of 50, it takes around 3 seconds. But it's a one-off operation, after these game badges are cached, it will detect that all games have an icon and don't need redownloading.

Copy link
Owner

@stenzek stenzek left a comment

Choose a reason for hiding this comment

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

I'd prefer it be a separate action. It really is a different operation - this one could take some time depending on the number of games (and thus needs progress), whereas the progress refresh is near-instant.

progress->SetStatusText(fmt::format("Fetching icon info for {} games...", game_ids.size()).c_str());

// Create HTTP downloader
std::unique_ptr<HTTPDownloader> http = HTTPDownloader::Create(Host::GetHTTPUserAgent());
Copy link
Owner

Choose a reason for hiding this comment

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

This can use the existing downloader for achievements if they're active, but that's a larger change - I can handle that afterwards - saves creating a worker thread.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I really wanted to simplify this. If you can handle it, that'd be great.

http->SetTimeout(30.0f);

// Fetch game titles (includes badge names) from RetroAchievements
rc_api_fetch_game_titles_request_t titles_request;
Copy link
Owner

Choose a reason for hiding this comment

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

This really should be implemented in rc_client, I'm trying to avoid using rc_api directly. But again, I can do that post-merge.

Copy link
Contributor Author

@mariobob mariobob Dec 4, 2025

Choose a reason for hiding this comment

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

I like the sound of that. Then other consumers would be able to use it too.


EDIT:
Is this what you meant? RetroAchievements/rcheevos#484
If so, then the code in achievements.cpp can be reduced down to this: mariobob#1 (this is just a preview, I'll be able to create a real PR once the current once is merged)

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 this pull request may close these issues.

3 participants