---
name: pp-game-goat
description: "Look up any game, find what to play next, and browse the Steam store from one CLI - RAWG search and ratings, remake-aware title resolution, and IsThereAnyDeal price history."
author: "Brad Knight"
license: "Apache-2.0"
argument-hint: "<command> [args] | install cli|mcp"
allowed-tools: "Read Bash"
metadata:
  openclaw:
    requires:
      bins:
        - game-goat-pp-cli
    install:
      - kind: go
        bins: [game-goat-pp-cli]
        module: github.com/mvanhorn/printing-press-library/library/media-and-entertainment/game-goat/cmd/game-goat-pp-cli
---
<!-- GENERATED FILE — DO NOT EDIT.
     This file is a verbatim mirror of library/media-and-entertainment/game-goat/SKILL.md,
     regenerated post-merge by tools/generate-skills/. Hand-edits here are
     silently overwritten on the next regen. Edit the library/ source instead.
     See the repository agent guide, section "Generated artifacts: registry.json, cli-skills/". -->

# Game GOAT — Printing Press CLI

## Prerequisites: Install the CLI

This skill drives the `game-goat-pp-cli` binary. **You must verify the CLI is installed before invoking any command from this skill.** If it is missing, install it first:

1. Install via the Printing Press installer. It defaults binaries to `$HOME/.local/bin` on macOS/Linux and `%LOCALAPPDATA%\Programs\PrintingPress\bin` on Windows:
   ```bash
   npx -y @mvanhorn/printing-press-library install game-goat --cli-only
   ```
2. Verify: `game-goat-pp-cli --version`
3. Ensure the reported install directory is on `$PATH` for the agent/runtime that will invoke this skill.

If the `npx` install fails (no Node, offline, etc.), fall back to a direct Go install (requires Go 1.26.6 or newer). This installs into `$GOPATH/bin` (default `$HOME/go/bin`), so add that directory to `$PATH` instead:

```bash
go install github.com/mvanhorn/printing-press-library/library/media-and-entertainment/game-goat/cmd/game-goat-pp-cli@latest
```

If `--version` reports "command not found" after install, the runtime cannot see the binary directory on `$PATH`. Do not proceed with skill commands until verification succeeds.

### What this CLI covers
- 350,000+ games across 50 platforms via RAWG (Video Games Database) (tags, genres, developers, publishers, creators, Metacritic scores, store links).
- Keyless Steam enrichment: review scores and player counts joined into rating cards.
- Remake-aware title resolution: shared names (DOOM 1993 vs 2016, franchise shorthand like "halo") resolve with a notice on stderr and meta.ambiguous in JSON; pin with --year or a RAWG id.
- One free RAWG API key powers live commands (see Auth Setup); local search over synced data works offline.
- IsThereAnyDeal historical and current price tracking (needs ITAD_API_KEY): all-time / 1-year / 3-month lows, a dated change log, and per-storefront current prices, localised to a --country currency.

### Terms of Use
- Free for personal use as long as you attribute RAWG as the source of the data and/or images and add an active
hyperlink from every page where the data of RAWG is used.
- Free for commercial use for startups and hobby projects with not more than 100,000 monthly active users or 500,000
page views per month. If your project is larger than that, email us at [api@rawg.io](mailto:api@rawg.io) for
commercial terms.
- No cloning. It would not be cool if you used our API to launch a clone of RAWG. We know it is not always easy
to say what is a duplicate and what isn't. Drop us a line at [api@rawg.io](mailto:api@rawg.io) if you are in doubt,
and we will talk it through.
- You must include an API key with every request. The key can be obtained at https://rawg.io/apidocs.
If you don’t provide it, we may ban your requests.

__[Read more](https://rawg.io/apidocs)__.

## When Not to Use This CLI

Do not activate this CLI for requests that require creating, updating, deleting, publishing, commenting, upvoting, inviting, ordering, sending messages, booking, purchasing, or changing remote state. Also do not use it for game news, esports schedules, purchasing or checkout, or running/emulating games — RAWG (Video Games Database) exposes none of these, and this CLI never buys anything. It does read prices: `price-history` and `prices` pull historical and current storefront prices from IsThereAnyDeal (read-only, requires ITAD_API_KEY). This printed CLI exposes read-only commands against the API for inspection, export, sync, and analysis.

## Unique Capabilities

These capabilities aren't available in any other tool for this API.
- **`similar`** — Games like <title>: the seed's own studio first, then its defining gameplay tag (roguelite, metroidvania) found by tag-neighborhood co-occurrence, then a confidence-floored genre join. Every row carries its tier and a reason.
- **`retention`** — Community completion and drop verdict for one game from RAWG added_by_status counts (needs RAWG_API_KEY).
- **`price-history`** — Historical price tracking for one game: all-time / 1-year / 3-month lows, the current best storefront price, a dated change log, and a buy-now verdict, localised to a --country currency (needs ITAD_API_KEY).
- **`prices`** — Current prices across storefronts, cheapest first, with a --deals-only filter and the all-time low for context, localised to a --country currency (needs ITAD_API_KEY).
- **`steam search`** — Plural keyless search of the Steam store across games, demos, DLC, soundtracks, software, video, mods, and hardware, with store tags, price, release date, platforms, and demo links on every row.
- **`steam browse`** — Paginated Steam catalog browse filtered by app type, free-only, store tag, and coming-soon/released, localised with `--country`; "every free demo in my region" is one command.
- **`steam demos`** — Demos only, each with the full game it belongs to: filter by `--tag` (every tag required, repeatable or comma-separated) or a single `--title` batch; released demos by default, `--coming-soon` for unreleased.

## Command Reference

**creator-roles** — List and get creator roles

- `game-goat-pp-cli creator-roles` — Get a list of creator positions (jobs).

**creators** — List and get creators

- `game-goat-pp-cli creators list` — Get a list of game creators.
- `game-goat-pp-cli creators read` — Get details of the creator.

**developers** — List and get developers

- `game-goat-pp-cli developers list` — Get a list of game developers.
- `game-goat-pp-cli developers read` — Get details of the developer.

**games** — List and get games

- `game-goat-pp-cli games list` — Get a list of games.
- `game-goat-pp-cli games read` — Get details of the game.

**genres** — List and get genres

- `game-goat-pp-cli genres list` — Get a list of video game genres.
- `game-goat-pp-cli genres read` — Get details of the genre.

**platforms** — List and get platforms

- `game-goat-pp-cli platforms list` — Get a list of video game platforms.
- `game-goat-pp-cli platforms lists-parents-list` — For instance, for PS2 and PS4 the “parent platform” is PlayStation.
- `game-goat-pp-cli platforms read` — Get details of the platform.

**publishers** — List and get publishers

- `game-goat-pp-cli publishers list` — Get a list of video game publishers.
- `game-goat-pp-cli publishers read` — Get details of the publisher.

**stores** — List and get stores

- `game-goat-pp-cli stores list` — Get a list of video game storefronts.
- `game-goat-pp-cli stores read` — Get details of the store.

**tags** — List and get tags

- `game-goat-pp-cli tags list` — Get a list of tags.
- `game-goat-pp-cli tags read` — Get details of the tag.

**games — discovery and detail**

- `game-goat-pp-cli games search` — live title search with remake-aware ambiguity notices.
- `game-goat-pp-cli games get` — full game detail by title or RAWG id.
- `game-goat-pp-cli games popular` — most-added games feed.
- `game-goat-pp-cli games top-rated` — highest-rated games feed.
- `game-goat-pp-cli games upcoming` — releases in the next 90 days.
- `game-goat-pp-cli discover` — RAWG's filter surface (genres, tags, platforms, stores, dates, ordering, metacritic).

**ratings · retention · series · similar**

- `game-goat-pp-cli ratings <title>` — RAWG + Metacritic + Steam rating card (title or bare RAWG id).
- `game-goat-pp-cli retention <title>` — community beaten/dropped/playing/yet split with an aspirational-trap verdict (needs RAWG_API_KEY).
- `game-goat-pp-cli series <title>` — franchise play order by release date, anchor included (title or bare RAWG id).
- `game-goat-pp-cli similar <title>` — tiered recommendations: same studio (capped), defining gameplay tag, then shared genres; each row carries `tier` and `reason` (title or bare RAWG id).

**prices — IsThereAnyDeal history and storefront prices**

- `game-goat-pp-cli price-history <title>` — all-time / 1-year / 3-month lows, the current best price, a dated change log, and a buy-now verdict; prices localised by `--country` (needs ITAD_API_KEY).
- `game-goat-pp-cli prices <title>` — current prices across storefronts, cheapest first, with `--deals-only` and `--limit`; localised by `--country` (needs ITAD_API_KEY).

**framework**

- `sync`, `search`, `analytics` — local SQLite mirror and offline search; `tail` polls the live API; `export` streams live API data to a file.
- `which`, `workflow`, `api`, `agent-context`, `profile`, `feedback`, `doctor` — agent-native plumbing.


**steam** — Keyless Steam store catalog: search, app records, filtered browse

- `game-goat-pp-cli steam search <term>` — Search the Steam store catalog for games, demos, DLC, soundtracks, and more.
- `game-goat-pp-cli steam app <appid|title>` — One full typed Steam store record, including demo links and the review summary.
- `game-goat-pp-cli steam browse` — Paginated Steam catalog browse with type, free, tag, and release filters.
- `game-goat-pp-cli steam demos` — Demos-only listing with the full game each demo belongs to; released by default, filter by `--tag` (every tag required) or one `--title` batch.

### Finding the right command

When you know what you want to do but not which command does it, ask the CLI directly:

```bash
game-goat-pp-cli which "<capability in your own words>"
```

`which` resolves a natural-language capability query to the best matching command from this CLI's curated feature index. Exit code `0` means at least one match; exit code `2` means no confident match — fall back to `--help` or use a narrower query. `--json` (and other machine formats) keep that exit-2 contract and write `{"matches":[]}` on stdout so agents can inspect the envelope without treating a miss as success.

## Recipes

### Games like one you loved

```bash
game-goat-pp-cli similar "Megabonk" --json --select results.name,results.tier,results.reason
```

### Play a franchise in order

```bash
game-goat-pp-cli series "zelda" --json
```

### Pin a remake when titles collide

```bash
game-goat-pp-cli ratings "resident evil 4" --year 2023 --json
```

A pinned `--year` is a hard constraint on the title too: if no game with that exact title was released in that year, the command reports not-found (drop `--year` or pass a RAWG id) rather than resolving a different game from the same year.

### Will people actually finish it?

```bash
game-goat-pp-cli retention "elden ring" --json
```

### Is now the cheapest it has ever been?

```bash
game-goat-pp-cli price-history "elden ring" --json
```

Historical lows (all-time, 1 year, 3 months), the current best storefront price, and a dated change log. Prices are localised to `--country` (ISO 3166-1 alpha-2; default `ITAD_COUNTRY` or US), so `--country GB` returns GBP. Requires an IsThereAnyDeal key — the `ITAD_API_KEY` env var or one stored via `auth set-token --provider itad`; get a free key at https://isthereanydeal.com/apps/.

### What does it cost where I live?

```bash
game-goat-pp-cli prices "elden ring" --country GB --deals-only --json
```

Current price at every storefront, cheapest first, plus the all-time low for context. `--deals-only` keeps just active discounts; `--limit` caps the rows.

### Search the Steam store

```bash
game-goat-pp-cli steam search "hollow knight" --json --select results.name,results.price,results.release_date
```

The keyless store search returns typed records: app type, release date, platforms, store tags, price, and the app's own demo links. `--type` takes a comma-separated list (game, demo, dlc, soundtrack, software, video, mod, hardware) and `--limit` goes up to 100. Text search has no second page — Valve's search service ignores an offset — so use `steam browse` when you need to page.

### Every free demo in my region

```bash
game-goat-pp-cli steam browse --type demo --free --country DE --page 2 --agent
```

Filtered catalog browse with real pagination: `--type`, `--free`, `--tag <name|tagid>` (repeat it or comma-separate; every tag is required), and `--coming-soon`/`--released`. `meta` carries `total`, `page`, `limit`, and `next_page`. Free-to-play and early access are attributes of a record rather than app types, so `--free` is how you ask for them.

### Find a demo by tag or title

```bash
game-goat-pp-cli steam demos --tag Roguelike --limit 20 --agent
game-goat-pp-cli steam demos --title portal --agent
```

`steam demos` is demos only: it fixes the app type to `demo` and never returns full games, and every row carries `parent_app_id`, `parent_name`, and `parent_tags` (the full game's store tag names, in Steam's order) for the full game it belongs to. The tags shown are the full game's: demos rarely carry tags of their own, so a demo's own tags appear as `tags` only when Steam lists any, and the human table's "full game tags" column shows the first three `parent_tags`. A bare `steam demos` lists the first page. Free-to-play titles are not demos, so use `steam browse --free` for those. Both paths return released demos ("available now") by default; `--coming-soon` swaps that for unreleased demos only, applied server-side so `meta.total` is the service's matching count. `--tag <name|tagid>` requires every tag (repeat it or comma-separate), and `--title` is a single search batch that defaults to 100 results (`--limit` up to 1000) and reports `meta.truncated` instead of a page cursor — `--page` is rejected with `--title`.

Request budget per invocation (unchanged): a browse page costs 3 requests (one catalog query, one tag-name dictionary lookup, and one lookup for the full-game names AND tags of every parent on the page); the tag-name dictionary is fetched once and shared with `--tag` resolution and the parent lookup, so adding `--tag` adds no request; a `--title` batch costs 1 search request, 1 tag-dictionary request, plus one full-game name+tag lookup per 200 games.

`steam app` always carries a `has_demo` boolean, and `ratings` adds `has_demo` and `demo_app_ids` when Steam resolves the game's appid. `discover` and `similar` can annotate every result with `has_demo` and `demo_app_ids` too, opt-in via `--with-demos`, which costs 1 extra RAWG request per result for its Steam store link plus 1 Steam request per 200 games.

The full Steam data-source note (which endpoints are used, why `STEAM_API_KEY` is not needed, and the bundle limitation) is the "Steam data sources" section of the README.

## Auth Setup
Run `game-goat-pp-cli auth setup` to print the URL and steps for getting a key (add `--launch` to open the URL). Then set:

```bash
export RAWG_API_KEY="<your-key>"
```
To persist credentials, use `echo "$TOKEN" | game-goat-pp-cli auth set-token`. Stored secrets live in `credentials.toml` under the data dir, not in `config.toml`.

The `steam` commands need no key at all: they use Valve's keyless store services. `STEAM_API_KEY` is not used anywhere in this CLI; the key-gated Steam Web API (players, achievements, stats) is the separate `steam-web` CLI.

### IsThereAnyDeal price data (optional)

`price-history` and `prices` read from IsThereAnyDeal and need their own free API key, independent of the RAWG key. Store it once (recommended) or export it per shell:

```bash
echo "$ITAD_API_KEY" | game-goat-pp-cli auth set-token --provider itad   # writes credentials.toml (0600)
# or: export ITAD_API_KEY="<your-key>"
```

Create a key at https://isthereanydeal.com/apps/. Prices are returned in the currency of the selected storefront country: pass `--country <ISO-3166-1>` (e.g. `GB`, `DE`) or set `ITAD_COUNTRY` for a default; without either, US/USD is used. A missing key surfaces as exit code 4 with setup guidance, not an upstream error.

Run `game-goat-pp-cli doctor` to verify setup.

## Agent Mode

Add `--agent` to any command. Expands to: `--json --compact --no-input --no-color`.

Global format flags share one contract on promoted, novel, sync, and `--deliver` paths:

- `--json` — one JSON document on stdout (sync progress events go to stderr)
- `--compact` — keep identity/status/timestamp fields; does not change the document vs stream shape
- `--csv` / `--plain` — tabular rows (collection envelopes unwrap to the row array)
- `--quiet` — one identity value per row, no envelope

- **Pipeable** — JSON on stdout, errors on stderr
- **Filterable** — `--select` keeps a subset of fields. Dotted paths descend into nested structures; arrays traverse element-wise. Critical for keeping context small on verbose APIs:

  ```bash
  game-goat-pp-cli creator-roles --agent --select id,name,slug
  ```
- **Previewable** — `--dry-run` shows the request without sending
- **Offline-friendly** — sync/search commands can use the local SQLite store when available
- **Non-interactive** — never prompts, every input is a flag
- **Read-only** — do not use this CLI for create, update, delete, publish, comment, upvote, invite, order, send, or other mutating requests

### Response envelope

Commands that read from the local store or the API wrap output in a provenance envelope:

```json
{
  "meta": {"source": "live" | "local", "synced_at": "...", "reason": "..."},
  "results": <data>
}
```

Parse `.results` for data and `.meta.source` to know whether it's live or local. A human-readable `N results (live)` summary is printed to stderr only when stdout is a terminal AND no machine-format flag (`--json`, `--csv`, `--compact`, `--quiet`, `--plain`, `--select`) is set — piped/agent consumers and explicit-format runs get pure JSON on stdout.

## Paths and state

Agents should treat the CLI's path resolver as part of the runtime contract:

- Use `--home <dir>` for one invocation, or set `GAME_GOAT_HOME=<dir>` to relocate all four path kinds under one root.
- Use per-kind env vars only when a specific kind must diverge: `GAME_GOAT_CONFIG_DIR`, `GAME_GOAT_DATA_DIR`, `GAME_GOAT_STATE_DIR`, `GAME_GOAT_CACHE_DIR`.
- Resolution order is per-kind env var, `--home`, `GAME_GOAT_HOME`, XDG (`XDG_CONFIG_HOME`, `XDG_DATA_HOME`, `XDG_STATE_HOME`, `XDG_CACHE_HOME`), then platform defaults.
- `config` contains settings like `config.toml` and profiles. `data` contains `credentials.toml`, `data.db`, cookies, and auth sidecars. `state` contains persisted queries, jobs, and `teach.log`. `cache` contains regenerable HTTP/cache files.
- Stored secrets live in `credentials.toml` under the data dir. Existing legacy `config.toml` secrets are read for compatibility and leave `config.toml` on the first auth write.
- Run `game-goat-pp-cli doctor --fail-on warn` to surface path and credential-location warnings. `agent-context` exposes a schema v4 `paths` block for agents that need the resolved dirs.
- For MCP, pass relocation through the MCP host config. The MCP binary does not inherit CLI flags:

  ```json
  {
    "mcpServers": {
      "game-goat": {
        "command": "game-goat-pp-mcp",
        "env": {
          "GAME_GOAT_HOME": "/srv/game-goat"
        }
      }
    }
  }
  ```

Fleet precedence: an inherited per-kind env var overrides an explicit `--home` for that kind. Use `GAME_GOAT_HOME` or per-kind vars as durable fleet levers, and use `--home` only for a single invocation