App Icons and Store Art

Every place a game is installed or sold wants its picture in a form of its own: Android a set of launcher icons in five densities plus an adaptive icon in layers, macOS an .icns file, Windows an .ico, a web page a favicon and a manifest, the Wii’s Homebrew Channel a 128 × 48 banner, Google Play a 512 × 512 icon and a 1024 × 500 feature graphic, Steam half a dozen capsules. Instead of drawing and resizing each of these by hand, a game keeps one source – an icon of 1024 × 1024 pixels, and optionally art made for a particular place – and the tools make the rest.

The source is declared in the game’s pyproject.toml, which C++ games have too (it is where the launcher and acronmanager read the project from):

[tool.acron.app]
name = "My Game"                   # default: [project] name
id = "com.example.mygame"          # the application id
icon = "art/icon.png"              # square, 1024 x 1024 or larger

acronmanager assets (the launcher’s App Icons & Store Art button) then writes every platform’s files into build/app-assets/. acronmanager dist and the --web, --android and --wii builds run it first, and hand the results on to build_apps and to the CMake helpers of the SDKs (see below), so most games never call it themselves. It only rewrites the files when the art or the settings have changed (acronmanager assets --force does so anyway).

The art

icon

The icon, a square PNG of at least 1024 × 1024 pixels. It is used as it is on the desktops (scaled down for the small sizes), on Android before version 8, as the favicon and in the store art. Draw it the way macOS shows icons: the picture on a rounded square or another shape, with a transparent margin of about a tenth around it, or as a picture filling the whole square.

icon_foreground, icon_background

The two layers of the Android adaptive icon (Android 8 and later), each a square of 108 × 108 dp (432 × 432 pixels or larger). The launcher cuts the icon into its own shape – a circle, a squircle, a rounded square – showing at most the middle 72 dp, and moves the layers against each other; only the middle 66 dp circle is certain to be seen. So the foreground holds the subject, inside that circle, on transparency, and the background is a picture or a colour ("#1e6b4f") that fills the square. Without them, the layers are made from the icon: an icon that fills its shape is scaled so that its edges reach past every launcher’s mask, an icon of a logo on transparency is put whole inside the safe circle, on the colour of the icon’s edge.

icon_monochrome

The icon’s shape for Android 13’s themed icons: only its transparency counts. Without it, the launcher uses the coloured icon.

wii_icon

The Homebrew Channel’s icon, 128 × 48. Without it, one is made: the icon and the game’s name on the background colour.

key_art

Wide art for the stores, ideally 3840 × 2160 or larger, with the subject near the middle: it is cropped to each format. Steam’s library hero is only made from it (it must not carry the title, so draw it without). Without it, the store art is the icon beside (or above) the game’s name on the background colour – enough to fill a page while testing, not to sell a game.

feature_graphic

Google Play’s feature graphic, 1024 × 500 (else cropped from the key art, else made from the icon).

screenshots

Paths or patterns ("art/screens/*.png"). They are copied as opaque PNGs; a warning names any that Google Play would refuse (it takes 320 to 3840 pixels a side, the long side at most twice the short one).

title_font

A TrueType or OpenType font for the name on generated art (default: Pillow’s built-in font).

description, theme_color, out_dir

The text of the web manifest and the Linux launcher entry (default: the [project] description), the web page’s theme colour (default: the background colour), and where the files go (default build/app-assets).

What is made

android/res/mipmap-*dpi/

ic_launcher.png (the icon), ic_launcher_round.png, and the adaptive icon’s layers, in five densities

android/res/mipmap-anydpi-v26/

the adaptive icon (ic_launcher.xml, ic_launcher_round.xml)

android/adaptive/

the layers at 432 × 432, for build_apps

macos/AppIcon.icns

the macOS app icon

windows/icon.ico

16 to 256 pixels

linux/hicolor/<n>x<n>/apps/<id>.png

the freedesktop icon theme sizes,

linux/<id>.desktop

and a launcher entry

web/

favicon.ico, favicon-32.png, apple-touch-icon.png, icon-192.png, icon-512.png, icon-maskable-512.png, manifest.webmanifest and icons.html (the <head> tags)

wii/icon.png

the Homebrew Channel’s icon

store/google-play/

icon-512.png, feature-graphic-1024x500.png

store/steam/

header (920 × 430), small (462 × 174), main (1232 × 706), vertical (748 × 896) and library (600 × 900) capsules, the library hero (3840 × 1240)

store/itch/cover-630x500.png

the itch.io cover

store/screenshots/

the screenshots

assets.json

the index: every file, and where each tool finds its part

Without a project, the same is made from the command line:

python -m acronmanager.appassets --icon art/icon.png --name "My Game" -o out/

Where the files go

The SDKs’ CMake helpers take the icon as an option, and a variable for the case that the option is not given, which acronmanager sets when it configures the build:

acron_android_executable(... ICON <png|dir>)

A PNG (192 × 192 or larger), or a res directory such as build/app-assets/android/res. Default: ACRON_ANDROID_ICON (acronmanager build --android passes the generated one).

acron_web_executable(... ICON <png|dir>)

A directory of web icons, such as build/app-assets/web: its files go beside the page, and its icons.html replaces @ICONS@ in the page (in your own SHELL too). A single PNG is put beside the page as icon.png. Default: ACRON_WEB_ICON (acronmanager build --web passes the generated one).

acron_wii_homebrew_app(... ICON <png>)

The Homebrew Channel’s icon. Default: ACRON_WII_ICON (acronmanager build --wii passes the generated build/app-assets/wii/icon.png).

acronmanager dist of a desktop game puts macos/AppIcon.icns into the macOS app bundle.

A packaging script of the game’s own, run by acronmanager dist or dist --android ([tool.acron.dist] or [tool.acron.android] command), finds the files through the environment variable ACRON_APP_ASSETS, and assets.json there says where each one is: macos/AppIcon.icns for an app bundle, windows/icon.ico for the executable’s resource file, and so on.

The stores

store/ holds the art that store pages ask for, in their sizes. It is a start, not a finished page: Google Play wants the 512 × 512 icon and the feature graphic; Steam the capsules, a library hero and logo, and screenshots; itch.io a cover. Art drawn for these – the key art above all – makes the generated versions unnecessary. The stores’ current requirements are in their own documentation (Google Play, Steam).