From 5d3e8d0261cbba30845f83653f40e76efa4e8d58 Mon Sep 17 00:00:00 2001 From: Stan Runge Date: Sun, 25 Oct 2026 18:35:21 +0000 Subject: [PATCH] games: official logos for all 16 game trackers (self-hosted, one map in #lib/game-logos) shown by TrackerIcon everywhere games appear; coloured tile stays as fallback; logo credits on the artwork credits page --- src/lib/components/TrackerIcon.svelte | 66 ++++++++--- src/lib/game-logos.ts | 106 ++++++++++++++++++ src/lib/tracker-icons.test.ts | 13 +++ .../game-tracker/credits/+page.svelte | 20 ++++ static/game-logos/icons/bo2.png | Bin 0 -> 1341 bytes static/game-logos/icons/cs2.png | Bin 0 -> 6012 bytes static/game-logos/icons/cubing.svg | 29 +++++ static/game-logos/icons/factorio.png | Bin 0 -> 28310 bytes static/game-logos/icons/ksp.png | Bin 0 -> 18397 bytes static/game-logos/icons/lol.svg | 1 + static/game-logos/icons/minecraft.svg | 1 + static/game-logos/icons/osu.svg | 1 + static/game-logos/icons/overwatch.svg | 1 + static/game-logos/icons/pokemon.svg | 31 +++++ static/game-logos/icons/pubg.png | Bin 0 -> 22247 bytes static/game-logos/icons/r6.png | Bin 0 -> 40365 bytes static/game-logos/icons/smash.svg | 1 + static/game-logos/icons/sot.png | Bin 0 -> 15950 bytes static/game-logos/icons/tarkov.png | Bin 0 -> 41845 bytes static/game-logos/icons/valorant.svg | 1 + 20 files changed, 254 insertions(+), 17 deletions(-) create mode 100644 src/lib/game-logos.ts create mode 100644 static/game-logos/icons/bo2.png create mode 100644 static/game-logos/icons/cs2.png create mode 100644 static/game-logos/icons/cubing.svg create mode 100644 static/game-logos/icons/factorio.png create mode 100644 static/game-logos/icons/ksp.png create mode 100644 static/game-logos/icons/lol.svg create mode 100644 static/game-logos/icons/minecraft.svg create mode 100644 static/game-logos/icons/osu.svg create mode 100644 static/game-logos/icons/overwatch.svg create mode 100644 static/game-logos/icons/pokemon.svg create mode 100644 static/game-logos/icons/pubg.png create mode 100644 static/game-logos/icons/r6.png create mode 100644 static/game-logos/icons/smash.svg create mode 100644 static/game-logos/icons/sot.png create mode 100644 static/game-logos/icons/tarkov.png create mode 100644 static/game-logos/icons/valorant.svg diff --git a/src/lib/components/TrackerIcon.svelte b/src/lib/components/TrackerIcon.svelte index 1483449..efd5150 100644 --- a/src/lib/components/TrackerIcon.svelte +++ b/src/lib/components/TrackerIcon.svelte @@ -1,27 +1,59 @@ - + (failed = true)} + /> + +{:else} + +{/if} + + diff --git a/src/lib/game-logos.ts b/src/lib/game-logos.ts new file mode 100644 index 0000000..a057224 --- /dev/null +++ b/src/lib/game-logos.ts @@ -0,0 +1,106 @@ +// Official game logos for the game tracker: one self-hosted asset per game in +// static/game-logos/icons/, keyed like `gameTrackers[].icon` (game-). TrackerIcon uses +// this map everywhere games show up (header flyout, home and /trackers tiles, /start chips, +// the games switcher and each game page); a game without an entry keeps its tracker-icons tile. +// Square app icons/emblems are used instead of wide wordmarks so they stay legible at chip size. + +export type GameLogo = { + /** Path under static/ (no leading slash), resolved with `asset`/`resolve` at render time. */ + src: string; + /** Opaque square app icon: fill the whole tile instead of sitting padded on the dark tile. */ + bleed?: boolean; + /** Where the asset came from (shown on /projects/game-tracker/credits). */ + credit: string; + source: string; +}; + +const steamIcon = (appid: number) => `https://store.steampowered.com/app/${appid}/`; +const commons = (file: string) => + `https://commons.wikimedia.org/wiki/File:${encodeURIComponent(file.replaceAll(' ', '_'))}`; + +export const gameLogos: Record = { + 'game-osu': { + src: 'game-logos/icons/osu.svg', + credit: 'osu! logo (2016), Wikimedia Commons', + source: commons('Osu! Logo 2016.svg') + }, + 'game-cs2': { + src: 'game-logos/icons/cs2.png', + bleed: true, + credit: 'Counter-Strike 2 app icon, Steam', + source: steamIcon(730) + }, + 'game-pubg': { + src: 'game-logos/icons/pubg.png', + credit: 'PUBG: Battlegrounds icon, pubg.com', + source: 'https://pubg.com/' + }, + 'game-r6': { + src: 'game-logos/icons/r6.png', + bleed: true, + credit: 'Rainbow Six Siege app icon, Steam', + source: steamIcon(359550) + }, + 'game-tarkov': { + src: 'game-logos/icons/tarkov.png', + bleed: true, + credit: 'Escape from Tarkov app icon, Steam', + source: steamIcon(3932890) + }, + 'game-bo2': { + src: 'game-logos/icons/bo2.png', + bleed: true, + credit: 'Call of Duty: Black Ops II app icon, Steam', + source: steamIcon(202970) + }, + 'game-valorant': { + src: 'game-logos/icons/valorant.svg', + credit: 'Valorant logo (V mark, pink), Wikimedia Commons', + source: commons('Valorant logo - pink color version.svg') + }, + 'game-lol': { + src: 'game-logos/icons/lol.svg', + credit: 'League of Legends logomark, Simple Icons (Hextech gold)', + source: 'https://simpleicons.org/?q=league+of+legends' + }, + 'game-overwatch': { + src: 'game-logos/icons/overwatch.svg', + credit: 'Overwatch 2 logo (light emblem for dark tiles), Wikimedia Commons', + source: commons('Overwatch 2 logo.svg') + }, + 'game-minecraft': { + src: 'game-logos/icons/minecraft.svg', + credit: 'Minecraft grass block icon, Wikimedia Commons', + source: commons('Minecraft cube.svg') + }, + 'game-factorio': { + src: 'game-logos/icons/factorio.png', + credit: 'Factorio wheel logo, official Factorio press kit', + source: 'https://factorio.com/support/press-kit' + }, + 'game-ksp': { + src: 'game-logos/icons/ksp.png', + credit: 'Kerbal Space Program app icon, Steam', + source: steamIcon(220200) + }, + 'game-smash': { + src: 'game-logos/icons/smash.svg', + credit: 'Super Smash Bros. emblem, Wikimedia Commons (flame-coloured)', + source: commons('Smash Ball.svg') + }, + 'game-cubing': { + src: 'game-logos/icons/cubing.svg', + credit: 'World Cube Association logo, Wikimedia Commons', + source: commons('World Cube Association.svg') + }, + 'game-pokemon': { + src: 'game-logos/icons/pokemon.svg', + credit: 'Poké Ball icon, Wikimedia Commons', + source: commons('Poké Ball icon.svg') + }, + 'game-sot': { + src: 'game-logos/icons/sot.png', + credit: 'Sea of Thieves app icon (skull), Steam', + source: steamIcon(1172620) + } +}; diff --git a/src/lib/tracker-icons.test.ts b/src/lib/tracker-icons.test.ts index 1898b79..a293461 100644 --- a/src/lib/tracker-icons.test.ts +++ b/src/lib/tracker-icons.test.ts @@ -1,4 +1,6 @@ import { describe, expect, it } from 'vitest'; +import { existsSync } from 'node:fs'; +import { gameLogos } from './game-logos'; import { trackerIcons } from './tracker-icons'; import { gameTrackers, spottingTrackers, visibleTrackers } from './projects'; @@ -16,6 +18,17 @@ describe('tracker icons', () => { expect(new Set(keys.map((k) => trackerIcons[k].to)).size).toBe(keys.length); }); + it('gives every game a self-hosted official logo', () => { + const keys = gameTrackers.map((g) => g.icon ?? g.name); + for (const key of keys) { + const logo = gameLogos[key]; + expect(logo, key).toBeDefined(); + expect(logo.src, key).toMatch(/^game-logos\/icons\/[a-z0-9-]+\.(svg|png)$/); + expect(existsSync(`static/${logo.src}`), logo.src).toBe(true); + } + expect(Object.keys(gameLogos).sort()).toEqual([...keys].sort()); + }); + it('links every game to its own page under /trackers/games', () => { const slugs = gameTrackers.map((g) => g.href.replace('/trackers/games/', '')); for (const slug of slugs) expect(slug).toMatch(/^[a-z0-9-]+$/); diff --git a/src/routes/projects/game-tracker/credits/+page.svelte b/src/routes/projects/game-tracker/credits/+page.svelte index d1766a3..f0bdd1e 100644 --- a/src/routes/projects/game-tracker/credits/+page.svelte +++ b/src/routes/projects/game-tracker/credits/+page.svelte @@ -1,5 +1,8 @@ @@ -16,6 +19,23 @@ stores WebP copies for consistent, reliable display. Map imagery is shared across games in the same region; later-region landmark positions are approximate.

+

Game logos

+
    + {#each gameTrackers as game (game.href)} + {@const logo = gameLogos[game.icon ?? game.name]} + {#if logo} +
  • + +
    +

    {game.name}

    + {logo.credit} +
    +
  • + {/if} + {/each} +

Regional maps