Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add skills/citiesskylinesmodding/agents-plugins/gameface-drivingnpx skills add CitiesSkylinesModding/agents-plugins --skill gameface-drivinggit clone --depth 1 https://github.com/CitiesSkylinesModding/agents-pluginsWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/citiesskylinesmodding/agents-plugins/gameface-driving)<a href="https://agentmods.dev/skills/citiesskylinesmodding/agents-plugins/gameface-driving"><img src="https://agentmods.dev/badge/skills/citiesskylinesmodding/agents-plugins/gameface-driving.svg" alt="Measured on agentmods" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00112 | $0.03149 |
| Opus 5 | $0.00056 | $0.01574 |
| Sonnet 5 | $0.00022 | $0.00630 |
| Haiku 4.5 | $0.00011 | $0.00315 |
Grade A, and why
gameface-driving scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured yesterday.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 95 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Driving a Gameface UI
This skill records the procedure for the game_* tools: the facts the tool schemas cannot tell you.
Facts that may be game-specific are labeled; the reference target is Cities: Skylines II (CS2, Cohtml 1.64.0.7).
For what the engine itself supports (layout, events, missing platform APIs), load the gameface skill; this one stays operational.
Session start and triage
Screenshot first and orient before acting: menus, dialogs, or a loading screen change what is safe to click.
A capture holds the UI view alone: the application's own rendering never reaches it, and every transparent region comes back flat white, so an expanse of white is the normal backdrop of a HUD rather than a blank or broken UI.
Read the application's state from what its UI displays, never from the scene behind it.
When any tool fails, run game_status before retrying; it settles whether the endpoint is reachable and which engine and page answered.
Read the page identity from target.url (for example assetdb://gameui/index.html).
A dead endpoint mid-session usually means the game crashed or was closed.
Report it and wait for the developer to relaunch the game; retry-looping cannot help, and testing that was interrupted mid-action may have left the UI in a state worth re-checking with a screenshot once the game is back.
No reconnect ritual exists or is needed: the server re-resolves the page target on the next call after the game returns.
Finding elements
game_query is the built-in element search; the schema covers its parameters, so what follows is how to read and use it.
Text is the durable anchor where the UI shows it and an attribute selector is the one where it does not; attributes: true on a match reveals which attribute the next query should anchor on.
Its three counts cascade: unprunedTotal (what the selector and text filter produced), total (after deepest pruning), and returned (after limit); total above returned means the limit truncated, so narrow the query, while unprunedTotal above total just shows how many ancestors deepest pruned.
deepest exists because an element's textContent includes its descendants': a panel and its title button both match the title, and deepest prunes the panel; pass deepest: false when you want the enclosing container (finding a panel by its title), and note a query no text drives — a selector alone, or text: '' — has no such bleed to correct.
tag: true handles die on the next tagging call and on any view reload; re-tag rather than reusing a stale handle.
When a selector is non-unique but the match order is known, the input tools' index parameter is a lighter alternative to tagging; each tool reports Matches: N so you can tell whether the selector was ambiguous, and an out-of-range index reports the match count so you can correct it.
Narrow with game_query, then read the one element you settled on with game_dom.
For a predicate no selector can express here (computed state, or picking a parent by what its children are, since :has() throws), scan manually from game_eval: [...document.querySelectorAll('button')].find(el => ...), then tag the node with el.setAttribute('data-probe', '1') and target [data-probe] when you need a unique selector, removing it after.
There is no XPath, no TreeWalker, and no innerText to lean on (engine gaps; details in the gameface skill).
The JS query APIs answer a short set of pseudo-classes and throw "Invalid CSS selector" on the rest: combinators, [attr*=], :first-child, :last-child, :only-child, :nth-child(), :root, :hover, :focus, :active, ::before and ::after are what is verified to work on CS2, and :not(), :has(), :is(), :where(), the of-type family, :nth-last-child(), :empty, :checked and :disabled are verified to throw; treat anything in neither list as untested rather than as supported.
:nth-child() itself takes an integer, even, odd, or a bare an step; an an+b offset (n+2, -n+3) throws like an unsupported pseudo-class.
Every selector-taking tool names the construct it suspects and a rewrite when it hits the rejection, game_eval and game_debug_evaluate included, falling back to the supported set when it can pin no construct: act on what it names rather than retrying the selector.
game_console is the exception, streaming page exceptions as the engine wrote them, so a rejection surfacing there arrives bare.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- yesterday Changed · +2 lines f2b485e7a1c6
- 6d ago First seen · 93 lines · 112 tokens per session scan A 32782df1c1e8
gameface-driving is a skill published in the GitHub repository CitiesSkylinesModding/agents-plugins (5 stars, last pushed 3d ago), licensed MIT. It adds 112 tokens to every session and 3,149 once invoked, about $0.0006 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
Other skills, from other repositories
mastering-engineer
Guides audio mastering for streaming platforms including loudness optimization and tonal balance. Use when the user has approved tracks and wants to master audio files.
promo-writer
Generates platform-specific social media copy from album themes, track concepts, and lyrics. Use when promo/ templates need to be populated before release.
researcher
Conducts investigative-grade research with primary source analysis, cross-verification, and trial-level depth. Use when an album needs factual research, source material, or verification of claims.
voice-checker
Reviews lyrics and prose for AI-written patterns (abstract noun stacking, over-explained metaphors, cliche escalation, missing idiosyncrasy, prose AI tells). Advisory Warning/Info severity — flags issues, does not block or rewrite. Use when reviewing lyrics for authenticity or before generation to catch AI-sounding…
validate-album
Validates album directory structure, file locations, and content integrity. Use before release or whenever the user wants to check an album's structural health.
promo-director
Generates 15-second vertical promo videos for social media from mastered audio. Use after mastering is complete and before release, when the user wants social media content.