From 5e2137851df88613a77123a88ab3bc67f007c2c6 Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Wed, 17 Jun 2026 18:37:44 -0700 Subject: [PATCH 1/9] docs: design for converting Pathfinder extensions to GDL --- ...-06-17-pathfinder-gdl-conversion-design.md | 245 ++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 docs/superpowers/specs/2026-06-17-pathfinder-gdl-conversion-design.md diff --git a/docs/superpowers/specs/2026-06-17-pathfinder-gdl-conversion-design.md b/docs/superpowers/specs/2026-06-17-pathfinder-gdl-conversion-design.md new file mode 100644 index 0000000000..28d3c6843f --- /dev/null +++ b/docs/superpowers/specs/2026-06-17-pathfinder-gdl-conversion-design.md @@ -0,0 +1,245 @@ +# Pathfinder extensions to GDL: design + +Date: 2026-06-17 +Branch: `halgari/pathfinder-to-gdl` (off `halgari/games-to-gdl-1`) + +## Goal + +Convert the two Owlcat Pathfinder game extensions to the Game Description +Language (GDL), the same declarative toolchain the X Rebirth extension now uses. + +- `extensions/games/game-pathfinderkingmaker` (currently `src/index.js`) +- `extensions/games/game-pathfinderwrathoftherighteous` (currently `src/index.ts`) + +Both become pure `game.yaml` with no `src/hooks.ts`. One new GDL feature is +added in the `game-description-language` submodule to cover the only behaviour +that GDL cannot express today. + +## What the two extensions do today + +| | Kingmaker | Wrath of the Righteous | +| --------------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | +| Stores | Steam `640820` | Steam `1184370`, GOG `1207187357` | +| Mods path | `Mods/` | `Mods/` | +| `requireExtension("modtype-umm")` | yes | yes | +| UMM registration | none; setup shows a manual "install UMM" dialog after a registry probe | `context.once(() => api.ext.ummAddGame({ gameId, autoDownloadUMM: true }))` | +| getGameVersion | none | reads `Wrath_Data/StreamingAssets/Version.info`, takes the 4th space-delimited token | +| Installers / modTypes | none | none | + +Neither game registers a custom installer or mod type. Game mods deploy to the +`Mods/` folder through Vortex's default path. The `umm` mod type (UMM the tool) +comes from the separate `modtype-umm` extension and only activates for a game +once that game has called `ummAddGame`. Kingmaker never calls it, so the `umm` +mod type is inert for Kingmaker today. + +## Key decisions + +These were settled during brainstorming. + +1. **Unify both games on a file-check plus download prompt.** Drop the + `modtype-umm` integration from both games. WotR loses its `ummAddGame` + auto-download and `umm` mod-type activation. This is an accepted behaviour + regression for WotR in exchange for both games becoming self-contained + declarative extensions. Game mods continue to deploy to `Mods/` exactly as + before; the change only affects how the UMM tool itself is obtained (a prompt + instead of auto-download). + +2. **`requireExtension("modtype-umm")` is dropped from both.** Once neither game + calls `ummAddGame`, the dependency is inert (the `umm` mod type never matches + either game), so it carries no behaviour. GDL therefore needs no + `requireExtension` support and no general init hook. + +3. **The file lookup is purely path based.** No registry reads. GDL deliberately + removed all `winapi` access and we keep it that way. For UMM this shifts the + meaning of the check from "is the UMM tool installed anywhere on the system" + (the old registry probe) to "is UMM set up in this game's folder." Accepted. + +4. **The prompt's download target opens a page, it does not silently install.** + The target is either a Nexus mod reference (`domain` + `modId`) that opens + `https://www.nexusmods.com//mods/`, or a plain `url`. Both + resolve to a single `util.opn(...)` call. A true one-click install would + require pinning a `fileId` per release, which is maintenance churn we avoid. + +## New GDL feature: `setup.requireFiles` + +GDL's `setup:` block today supports only `ensureDirs`. We extend it with an +optional `requireFiles` step that runs during the game's `setup` lifecycle, +right after `ensureDirs`. + +### YAML shape + +```yaml +setup: + ensureDirs: + - ${installPath}/Mods + requireFiles: + files: + - ${installPath}/UnityModManager/UnityModManager.dll + prompt: + title: Action required + message: You must install Unity Mod Manager to use mods with this game. + link: + label: Go to the Unity Mod Manager page + mod: { domain: site, modId: 21 } # or: url: https://example.com/... +``` + +### Field rules + +- `requireFiles` is optional inside `setup`. +- `files` is a non-empty list of path templates, interpolated against the + runtime context (`${installPath}`, etc.). The validator rejects an empty list. +- `prompt.title` and `prompt.message` are required when `requireFiles` is present. +- `prompt.link` is optional. + - `link.label` is the button text (required when `link` is present). + - Exactly one of `link.mod` or `link.url` must be set. + - `link.mod` is `{ domain: , modId: }`. + - `link.url` is a string. + +### Runtime semantics + +Implemented in the runtime shim's generated `game.setup`, after `ensureDirs`: + +1. Resolve every `files` template against the resolved context and `fs.statAsync` + each one. +2. If all exist, do nothing. +3. If any are missing, call `api.showDialog`: + - Type `info`, title `prompt.title`, body text `prompt.message`. + - Buttons: a `Cancel`/`Close` button, plus (when `link` is present) a button + labelled `link.label` whose action calls `util.opn(targetUrl)`, where + `targetUrl` is `link.url` or `https://www.nexusmods.com//mods/` + built from `link.mod`. +4. The step is informational. It does not reject `setup`. + +The original Kingmaker code rejected `setup` with `UserCanceled` after the +dialog. We drop that quirk; a passive prompt that lets management proceed is +cleaner. This is the one intentional behaviour change beyond the registry to +path shift. + +### Where it lives in the toolchain + +The feature is implemented in the `game-description-language` submodule (its own +repo, `Nexus-Mods/game-description-language`, currently on `main`), touching: + +- `src/parser/ast.ts`: add `requireFiles?` to `SetupNode`, plus the supporting + node types for `files`, `prompt`, and `link`. +- `src/parser/index.ts`: parse the new keys under `setup`. +- `src/schema/validator.ts`: enforce the field rules above. +- `src/codegen/emit.ts` and `src/codegen/lifecycle-emit.ts`: thread the parsed + `requireFiles` data into the generated extension and `game.setup`. +- `src/runtime/vortex-shim.ts`: extend the generated `game.setup` to run the + stat-and-prompt logic. +- Tests in the GDL repo: parser, validator, codegen, and a runtime test that the + generated `setup` stats the listed files and fires the dialog when one is + missing. + +The Vortex branch then bumps the submodule pointer, matching the existing +pattern (the X Rebirth conversion landed GDL features as PR #2 in that repo, +followed by "bump game-description-language submodule" commits here). + +### Alternatives considered + +- **A new top-level `prerequisites:` block** instead of nesting under `setup`. + More general, but the only consumer right now is setup-time, so the extra + schema surface is not justified (YAGNI). Rejected. +- **A diagnostic / health check** using GDL's existing `diagnostics:` block. A + health check is a passive warning surface, so it cannot present the actionable + "go get UMM" button the original behaviour has. Rejected. +- **A registry-based lookup option** for faithful UMM detection. Rejected to + keep GDL free of `winapi` (decision 3). +- **One-click install via `nexus-download` / `nxm://` URL.** Requires a pinned + `fileId` per release. Rejected for the maintenance churn (decision 4). + +## Converted extensions + +Neither game needs a `src/hooks.ts`. Both become a single `game.yaml` plus the +GDL plumbing files (`package.json`, `build.mjs`, `tsconfig.json`, +`vitest.config.ts`), mirroring `game-xrebirth`. The `gameart.jpg` logos convert +to `gameart.webp`. + +### Kingmaker `game.yaml` (shape) + +```yaml +gdl: 1 +version: + +game: + id: pathfinderkingmaker + name: "Pathfinder: Kingmaker" + executable: Kingmaker.exe + requiredFiles: [Kingmaker.exe] + logo: gameart.webp + nexusDomain: pathfinderkingmaker + queryModPath: Mods + +stores: + steam: "640820" + +setup: + ensureDirs: + - ${installPath}/Mods + requireFiles: + files: + - ${installPath}/UnityModManager/UnityModManager.dll + prompt: + title: Action required + message: You must install Unity Mod Manager to use mods with Pathfinder: Kingmaker. + link: + label: Go to the Unity Mod Manager page + mod: { domain: site, modId: 21 } + +tests: + corpus: nexus +``` + +`environment.SteamAPPId` and `details.steamAppId` auto-derive from `stores.steam`, +so they are not set explicitly. Dropped from the original: the registry helpers, +Bluebird, the `process.platform` guard, and `requireExtension`. + +### WotR `game.yaml` (shape) + +Same as Kingmaker, with these differences: + +```yaml +game: + id: pathfinderwrathoftherighteous + name: "Pathfinder: Wrath of the Righteous" + executable: Wrath.exe + requiredFiles: [Wrath.exe] + nexusDomain: pathfinderwrathoftherighteous + queryModPath: Mods + +stores: + steam: "1184370" + gog: "1207187357" + +discovery: + version: + file: ${installPath}/Wrath_Data/StreamingAssets/Version.info + regex: '^(?:\S+\s+){3}(\S+)' # 4th space-delimited token, == old split(" ")[3] + +setup: + ensureDirs: + - ${installPath}/Mods + requireFiles: + # same UMM check as Kingmaker +``` + +Dropped from the original: `requireExtension`, the `ummAddGame` registration +(decision 1), and the imperative `getGameVersion` (now declarative via +`discovery.version`). + +## Testing + +- The new GDL feature is unit tested in the GDL repo (parser, validator, + codegen, runtime), including a runtime case that proves the dialog fires when a + required file is absent and stays silent when all are present. +- Each game opts into `tests: { corpus: nexus }` so the installer and deploy path + runs against real Nexus mod manifests, the same harness X Rebirth uses. The + corpus does not exercise `requireFiles`, which is setup-time only. + +## Open items to confirm during implementation + +- The exact UMM marker file path under the game directory. The `game.yaml` value + is trivially tunable; verify it against a real UMM-patched Pathfinder layout. +- Whether `version` should be sourced from each `package.json` (as X Rebirth + does) or pinned in `game.yaml`. From 370ad188b447cf7834607127184b6e819737c318 Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Wed, 17 Jun 2026 18:52:48 -0700 Subject: [PATCH 2/9] docs: implementation plan for Pathfinder GDL conversion --- .../2026-06-17-pathfinder-gdl-conversion.md | 1339 +++++++++++++++++ 1 file changed, 1339 insertions(+) create mode 100644 docs/superpowers/plans/2026-06-17-pathfinder-gdl-conversion.md diff --git a/docs/superpowers/plans/2026-06-17-pathfinder-gdl-conversion.md b/docs/superpowers/plans/2026-06-17-pathfinder-gdl-conversion.md new file mode 100644 index 0000000000..3d59f87dd5 --- /dev/null +++ b/docs/superpowers/plans/2026-06-17-pathfinder-gdl-conversion.md @@ -0,0 +1,1339 @@ +# Pathfinder to GDL Conversion Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Convert the two Owlcat Pathfinder game extensions (Kingmaker, Wrath of the Righteous) to run off the Game Description Language (GDL), adding one new declarative GDL feature (`setup.requireFiles`) to cover the Unity Mod Manager prompt. + +**Architecture:** Two phases. Phase A adds a `setup.requireFiles` block to the `game-description-language` submodule (parser, validator, codegen, runtime, type stub, tests). Phase B rewrites each Pathfinder extension as a single declarative `game.yaml`, deletes the old imperative source, and bumps the submodule pointer in Vortex. + +**Tech Stack:** TypeScript, GDL toolchain (YAML to webpack-bundled Vortex extension), vitest, pnpm workspaces, git submodule. + +--- + +## Design reference + +Full design: `docs/superpowers/specs/2026-06-17-pathfinder-gdl-conversion-design.md`. + +Settled decisions baked into this plan: + +- Both games drop `modtype-umm` integration (`requireExtension`, `ummAddGame`). They become self-contained. WotR loses UMM auto-download and `umm` mod-type activation (accepted regression). +- The UMM presence check is purely path based (no registry). +- The prompt button opens a Nexus mod page (`domain` + `modId`) or a plain `url`. No silent install. +- The `requireFiles` step is informational; it does not reject `setup` (the original Kingmaker `UserCanceled` quirk is dropped). + +## Deviations from the spec to confirm with the user + +- **No webp conversion.** No webp encoder is installed (`cwebp`/ImageMagick/sharp absent). The plan keeps `gameart.jpg` and references it directly. webp is optional polish, not a functional requirement. The GDL build copies whatever logo filename `game.yaml` names. +- **No `tests: { corpus: nexus }` in the game.yaml.** Both games register zero installers (mods deploy to `Mods/` via Vortex's default), so corpus installer-routing tests have nothing to assert. The `requireFiles` feature is fully unit-tested in the GDL repo instead. Game-side verification is the GDL build succeeding plus produced `dist/` artifacts. + +## File structure + +**Phase A — `game-description-language` submodule (separate repo, branch off `main`):** + +- Modify: `src/parser/ast.ts` — add `requireFiles?` to `SetupNode` and new node interfaces. +- Modify: `src/parser/index.ts` — parse `setup.requireFiles` (new `parseRequireFiles` helper). +- Modify: `src/schema/validator.ts` — field rules for `requireFiles`. +- Modify: `src/types/vortex-api.d.ts` — declare `fs.statAsync` and `api.showDialog`. +- Modify: `src/runtime/vortex-shim.ts` — `RequireFilesSpec` type, trailing `registerGame` param, setup logic, `runRequireFilesCheck` method. +- Modify: `src/codegen/emit.ts` — emit the `requireFiles` literal (build URL from `mod`). +- Test: `tests/require-files.test.ts` — parser, validator, runtime, codegen cases for the feature. + +**Phase B — Vortex repo (branch `halgari/pathfinder-to-gdl`, already created):** + +- For each of `extensions/games/game-pathfinderkingmaker/` and `extensions/games/game-pathfinderwrathoftherighteous/`: + - Create: `game.yaml`, `build.mjs`, `vitest.config.ts`, `gameart.jpg` (moved from `assets/`). + - Rewrite: `package.json`. + - Delete: `src/index.js` / `src/index.ts`, `assets/` (including unused `umm.png`), `tsconfig.tsbuildinfo`, any old build script. +- Modify: the submodule pointer (Vortex records the new `game-description-language` commit). + +--- + +# Phase A: GDL `setup.requireFiles` feature + +All Phase A work happens inside the submodule directory `game-description-language/`. Commands below assume you are `cd`'d into that directory unless stated otherwise. + +### Task A0: Create the feature branch in the submodule + +- [ ] **Step 1: Branch off main** + +Run (from repo root `/c/oss/Vortex`): + +```bash +git -C game-description-language fetch origin +git -C game-description-language checkout -B feat/setup-require-files origin/main +``` + +- [ ] **Step 2: Confirm clean baseline build and tests** + +Run: + +```bash +cd game-description-language && pnpm install --frozen-lockfile && pnpm build && pnpm test +``` + +Expected: build succeeds, full suite passes (the baseline ~154 tests green). + +--- + +### Task A1: AST types for `requireFiles` + +**Files:** + +- Modify: `game-description-language/src/parser/ast.ts:247-251` (the `SetupNode` interface) + +- [ ] **Step 1: Extend `SetupNode` and add node types** + +Replace the existing `SetupNode` interface (currently): + +```ts +export interface SetupNode extends Node { + kind: "setup"; + ensureDirs: string[]; // path templates, interpolated against context +} +``` + +with: + +```ts +export interface SetupNode extends Node { + kind: "setup"; + ensureDirs: string[]; // path templates, interpolated against context + requireFiles?: RequireFilesNode; +} + +// Declarative prerequisite check: stat a list of files at setup time and, when +// any are missing, show an informational dialog that points the user at a mod +// page or URL to download the missing prerequisite (e.g. Unity Mod Manager). +export interface RequireFilesNode { + files: string[]; // path templates, interpolated against context + prompt: RequireFilesPrompt; +} + +export interface RequireFilesPrompt { + title: string; + message: string; + link?: RequireFilesLink; +} + +export interface RequireFilesLink { + label: string; // button text + target: RequireFilesTarget; +} + +export type RequireFilesTarget = + | { kind: "mod"; domain: string; modId: number } + | { kind: "url"; url: string }; +``` + +- [ ] **Step 2: Typecheck** + +Run: `cd game-description-language && pnpm exec tsc --noEmit` +Expected: PASS (no references yet, types compile). + +- [ ] **Step 3: Commit** + +```bash +git -C game-description-language add src/parser/ast.ts +git -C game-description-language commit -m "feat(ast): add requireFiles to SetupNode" +``` + +--- + +### Task A2: Parse `setup.requireFiles` + +**Files:** + +- Modify: `game-description-language/src/parser/index.ts` (the `setup` block near line 884, plus a new helper) +- Test: `game-description-language/tests/require-files.test.ts` + +- [ ] **Step 1: Write the failing parser test** + +Create `game-description-language/tests/require-files.test.ts`: + +```ts +import { describe, it, expect } from "vitest"; +import { parseYaml } from "../src/parser/index.js"; + +const YAML = `gdl: 1 +game: + id: g + name: G + executable: G.exe + requiredFiles: [G.exe] +stores: + steam: "1" +setup: + ensureDirs: + - \${installPath}/Mods + requireFiles: + files: + - \${installPath}/UnityModManager/UnityModManager.dll + prompt: + title: Action required + message: Install UMM + link: + label: Get UMM + mod: { domain: site, modId: 21 } +`; + +describe("parser: setup.requireFiles", () => { + it("parses files, prompt, and a mod link target", () => { + const doc = parseYaml(YAML, "rf.yaml"); + const rf = doc.setup?.requireFiles; + expect(rf?.files).toEqual(["${installPath}/UnityModManager/UnityModManager.dll"]); + expect(rf?.prompt.title).toBe("Action required"); + expect(rf?.prompt.message).toBe("Install UMM"); + expect(rf?.prompt.link?.label).toBe("Get UMM"); + expect(rf?.prompt.link?.target).toEqual({ kind: "mod", domain: "site", modId: 21 }); + }); + + it("parses a url link target", () => { + const doc = parseYaml( + YAML.replace("mod: { domain: site, modId: 21 }", "url: https://example.com/umm"), + "rf.yaml", + ); + expect(doc.setup?.requireFiles?.prompt.link?.target).toEqual({ + kind: "url", + url: "https://example.com/umm", + }); + }); +}); +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `cd game-description-language && pnpm exec vitest run tests/require-files.test.ts` +Expected: FAIL (`rf` is undefined — parser ignores `requireFiles`). + +- [ ] **Step 3: Add the import and parse logic** + +In `src/parser/index.ts`, add the new AST types to the existing `ast.js` import (find the import line that already pulls `SetupNode` and add the new names): + +```ts +import type { + // ...existing imports... + SetupNode, + RequireFilesNode, + RequireFilesLink, + RequireFilesTarget, +} from "./ast.js"; +``` + +(Only add the names not already present; `SetupNode` is likely already imported.) + +Replace the existing `setup` assembly block (currently building `setup = { kind: 'setup', ensureDirs: dirs, span }`) so it also parses `requireFiles`: + +```ts +let requireFiles: RequireFilesNode | undefined; +const rfYaml = setupYaml.get("requireFiles", true); +if (isMap(rfYaml)) { + requireFiles = parseRequireFiles(rfYaml, file, source); +} +setup = { + kind: "setup", + ensureDirs: dirs, + ...(requireFiles !== undefined && { requireFiles }), + span: spanOf(file, source, setupYaml), +}; +``` + +Add this helper near the other parse helpers (e.g. just above `parseYaml` or beside `parseToolbarActionTarget`). It mirrors the structural-error style used by the `ensureDirs` parser: + +```ts +function parseRequireFiles(node: YAMLMap, file: string, source: string): RequireFilesNode { + const files: string[] = []; + const filesYaml = node.get("files", true); + if (isSeq(filesYaml)) { + for (const item of filesYaml.items) { + if (isScalar(item) && typeof item.value === "string") { + files.push(item.value); + } else { + throw new BuildErrors([ + { + code: "GDL153", + message: "setup.requireFiles.files entries must be strings", + span: spanOf(file, source, item as YamlNode), + }, + ]); + } + } + } + + const promptYaml = node.get("prompt", true); + if (!isMap(promptYaml)) { + throw new BuildErrors([ + { + code: "GDL154", + message: "setup.requireFiles.prompt must be a mapping with title and message", + span: spanOf(file, source, node), + }, + ]); + } + const title = String(promptYaml.get("title") ?? ""); + const message = String(promptYaml.get("message") ?? ""); + + let link: RequireFilesLink | undefined; + const linkYaml = promptYaml.get("link", true); + if (isMap(linkYaml)) { + const label = String(linkYaml.get("label") ?? ""); + const modYaml = linkYaml.get("mod", true); + const urlYaml = linkYaml.get("url", true); + let target: RequireFilesTarget; + if (isMap(modYaml)) { + target = { + kind: "mod", + domain: String(modYaml.get("domain") ?? ""), + modId: Number(modYaml.get("modId") ?? 0), + }; + } else if (isScalar(urlYaml) && typeof urlYaml.value === "string") { + target = { kind: "url", url: urlYaml.value }; + } else { + throw new BuildErrors([ + { + code: "GDL156", + message: + "setup.requireFiles.prompt.link must set exactly one of `mod` or `url`", + span: spanOf(file, source, linkYaml), + }, + ]); + } + link = { label, target }; + } + + return { files, prompt: { title, message, ...(link !== undefined && { link }) } }; +} +``` + +Note: `YAMLMap` and `YamlNode` types are already imported/used elsewhere in this file (see `parseToolbarActionTarget`); reuse the same type names. If `YAMLMap` is not yet imported, use the same `yaml` import the file already relies on. + +- [ ] **Step 4: Run test to verify it passes** + +Run: `cd game-description-language && pnpm exec vitest run tests/require-files.test.ts` +Expected: PASS (both parser cases). + +- [ ] **Step 5: Typecheck and commit** + +Run: `cd game-description-language && pnpm exec tsc --noEmit` +Expected: PASS. + +```bash +git -C game-description-language add src/parser/index.ts tests/require-files.test.ts +git -C game-description-language commit -m "feat(parser): parse setup.requireFiles" +``` + +--- + +### Task A3: Validate `requireFiles` + +**Files:** + +- Modify: `game-description-language/src/schema/validator.ts` (inside the `if (doc.setup)` block, after the `ensureDirs` checks near line 390-399) +- Test: `game-description-language/tests/require-files.test.ts` (append) + +- [ ] **Step 1: Write the failing validator tests** + +Append to `tests/require-files.test.ts`: + +```ts +import { validate } from "../src/schema/validator.js"; + +const baseYaml = (rf: string) => `gdl: 1 +game: + id: g + name: G + executable: G.exe + requiredFiles: [G.exe] +stores: + steam: "1" +setup: + ensureDirs: + - \${installPath}/Mods + requireFiles: +${rf} +`; + +describe("validator: setup.requireFiles", () => { + it("accepts a well-formed requireFiles block", () => { + const doc = parseYaml( + baseYaml( + ` files: + - \${installPath}/x.dll + prompt: + title: T + message: M + link: + label: L + mod: { domain: site, modId: 21 }`, + ), + "rf.yaml", + ); + expect(validate(doc).filter((e) => e.code.startsWith("GDL15"))).toEqual([]); + }); + + it("rejects an empty files list", () => { + const doc = parseYaml( + baseYaml( + ` files: [] + prompt: + title: T + message: M`, + ), + "rf.yaml", + ); + expect(validate(doc).some((e) => e.code === "GDL153")).toBe(true); + }); + + it("rejects a missing prompt title", () => { + const doc = parseYaml( + baseYaml( + ` files: + - \${installPath}/x.dll + prompt: + title: "" + message: M`, + ), + "rf.yaml", + ); + expect(validate(doc).some((e) => e.code === "GDL154")).toBe(true); + }); + + it("rejects a link with an empty mod domain", () => { + const doc = parseYaml( + baseYaml( + ` files: + - \${installPath}/x.dll + prompt: + title: T + message: M + link: + label: L + mod: { domain: "", modId: 21 }`, + ), + "rf.yaml", + ); + expect(validate(doc).some((e) => e.code === "GDL155")).toBe(true); + }); +}); +``` + +- [ ] **Step 2: Run to verify failure** + +Run: `cd game-description-language && pnpm exec vitest run tests/require-files.test.ts -t "validator: setup.requireFiles"` +Expected: FAIL (no GDL153/154/155 emitted yet). + +- [ ] **Step 3: Add validation** + +In `src/schema/validator.ts`, inside the existing `if (doc.setup) {` block, after the `ensureDirs` loop, add: + +```ts +const rf = doc.setup.requireFiles; +if (rf) { + if (rf.files.length === 0) { + errors.push({ + code: "GDL153", + message: "setup.requireFiles.files must not be empty", + span: doc.setup.span, + }); + } + rf.files.forEach((f, i) => { + if (f.trim() === "") { + errors.push({ + code: "GDL153", + message: `setup.requireFiles.files[${i}] must not be empty`, + span: doc.setup!.span, + }); + } + }); + if (rf.prompt.title.trim() === "") { + errors.push({ + code: "GDL154", + message: "setup.requireFiles.prompt.title must not be empty", + span: doc.setup.span, + }); + } + if (rf.prompt.message.trim() === "") { + errors.push({ + code: "GDL154", + message: "setup.requireFiles.prompt.message must not be empty", + span: doc.setup.span, + }); + } + if (rf.prompt.link) { + const link = rf.prompt.link; + if (link.label.trim() === "") { + errors.push({ + code: "GDL155", + message: "setup.requireFiles.prompt.link.label must not be empty", + span: doc.setup.span, + }); + } + if ( + link.target.kind === "mod" && + (link.target.domain.trim() === "" || + !Number.isFinite(link.target.modId) || + link.target.modId <= 0) + ) { + errors.push({ + code: "GDL155", + message: "setup.requireFiles.prompt.link.mod needs a domain and a positive modId", + span: doc.setup.span, + }); + } + if (link.target.kind === "url" && link.target.url.trim() === "") { + errors.push({ + code: "GDL155", + message: "setup.requireFiles.prompt.link.url must not be empty", + span: doc.setup.span, + }); + } + } +} +``` + +- [ ] **Step 4: Run to verify pass** + +Run: `cd game-description-language && pnpm exec vitest run tests/require-files.test.ts` +Expected: PASS (all parser + validator cases). + +- [ ] **Step 5: Typecheck and commit** + +Run: `cd game-description-language && pnpm exec tsc --noEmit` + +```bash +git -C game-description-language add src/schema/validator.ts tests/require-files.test.ts +git -C game-description-language commit -m "feat(validator): enforce setup.requireFiles field rules" +``` + +--- + +### Task A4: Extend the `vortex-api` type stub + +**Files:** + +- Modify: `game-description-language/src/types/vortex-api.d.ts:116-118` (`fs`) and `:93-98` (`api`) + +The runtime shim (Task A5) calls `fs.statAsync` and `api.showDialog`, neither of which the stub declares. Add them first so A5 typechecks. + +- [ ] **Step 1: Add `fs.statAsync`** + +Replace: + +```ts +export const fs: { + ensureDirWritableAsync: (path: string) => Promise; +}; +``` + +with: + +```ts +export const fs: { + ensureDirWritableAsync: (path: string) => Promise; + statAsync: (path: string) => Promise<{ isDirectory: () => boolean }>; +}; +``` + +- [ ] **Step 2: Add `showDialog` to the context `api` type** + +Replace the `api: { ... }` block inside `IExtensionContext` (currently `getState` + `events.on`) with: + +```ts + api: { + getState: () => unknown; + events: { + on: (event: string, handler: (...args: unknown[]) => void) => void; + }; + showDialog: ( + type: string, + title: string, + content: { text?: string; message?: string; bbcode?: string }, + actions: Array<{ label: string; action?: () => void }>, + ) => Promise; + }; +``` + +- [ ] **Step 3: Typecheck and commit** + +Run: `cd game-description-language && pnpm exec tsc --noEmit` +Expected: PASS. + +```bash +git -C game-description-language add src/types/vortex-api.d.ts +git -C game-description-language commit -m "feat(types): declare fs.statAsync and api.showDialog in stub" +``` + +--- + +### Task A5: Runtime — run the check and show the dialog + +**Files:** + +- Modify: `game-description-language/src/runtime/vortex-shim.ts` (add type, `registerGame` trailing param, setup logic, helper) +- Test: `game-description-language/tests/require-files.test.ts` (append) + +- [ ] **Step 1: Write the failing runtime tests** + +Append to `tests/require-files.test.ts`: + +```ts +import { GdlRuntime } from "../src/runtime/index.js"; +import { createFakeContext } from "../src/runtime/testing/index.js"; +import type { IExtensionContext } from "vortex-api"; +import { vi } from "vitest"; + +const RT_DECL = { id: "g", name: "G", executable: "G.exe", requiredFiles: ["G.exe"] }; +const RT_STORES = [{ id: "steam", value: "1" }]; +const RT_CTX = { bindings: [] }; +const RT_MODTYPES: never[] = []; +const RT_RF = { + files: ["${installPath}/UnityModManager/UnityModManager.dll"], + prompt: { + title: "Action required", + message: "Install UMM", + link: { label: "Get UMM", url: "https://www.nexusmods.com/site/mods/21" }, + }, +}; + +const dialogMock = (h: ReturnType) => + (h.context as unknown as { api: { showDialog: ReturnType } }).api.showDialog; + +describe("runtime: setup.requireFiles", () => { + beforeEach(() => vi.clearAllMocks()); + + it("shows the prompt when a required file is missing", async () => { + const { fs } = await import("vortex-api"); + vi.mocked(fs.statAsync).mockRejectedValue(new Error("ENOENT")); + const h = createFakeContext(); + const runtime = new GdlRuntime(h.context as IExtensionContext); + runtime.registerGame( + RT_DECL, + RT_STORES, + RT_CTX, + RT_MODTYPES, + [], + {}, + [], + [], + {}, + [], + RT_RF, + ); + const g = h.registered.game!; + await g.setup!({ path: "/games/g", store: "steam" }); + expect(dialogMock(h)).toHaveBeenCalledTimes(1); + expect(dialogMock(h).mock.calls[0][1]).toBe("Action required"); + }); + + it("stays silent when all required files exist", async () => { + const { fs } = await import("vortex-api"); + vi.mocked(fs.statAsync).mockResolvedValue({ isDirectory: () => false }); + const h = createFakeContext(); + const runtime = new GdlRuntime(h.context as IExtensionContext); + runtime.registerGame( + RT_DECL, + RT_STORES, + RT_CTX, + RT_MODTYPES, + [], + {}, + [], + [], + {}, + [], + RT_RF, + ); + await h.registered.game!.setup!({ path: "/games/g", store: "steam" }); + expect(dialogMock(h)).not.toHaveBeenCalled(); + }); +}); +``` + +- [ ] **Step 2: Run to verify failure** + +Run: `cd game-description-language && pnpm exec vitest run tests/require-files.test.ts -t "runtime: setup.requireFiles"` +Expected: FAIL (`registerGame` ignores the 11th arg; no dialog). + +- [ ] **Step 3: Add the `RequireFilesSpec` type** + +In `src/runtime/vortex-shim.ts`, near the other exported interfaces (e.g. after `EventHooks`), add: + +```ts +export interface RequireFilesSpec { + files: string[]; + prompt: { + title: string; + message: string; + link?: { label: string; url: string }; + }; +} +``` + +- [ ] **Step 4: Add the trailing `registerGame` parameter** + +Extend the `registerGame` signature. After the existing `diagnostics: IModHealthCheck[] = [],` parameter, add: + +```ts + requireFiles?: RequireFilesSpec, +``` + +- [ ] **Step 5: Run the check inside `game.setup`** + +Replace the existing setup block: + +```ts +if (setupDirs.length > 0) { + game.setup = async (discovery: IDiscoveryResult) => { + const { fs } = await import("vortex-api"); + const facts = this.factsFromDiscovery(discovery); + this.cachedFacts = facts; + this.resolvedCtx = resolveContext(contextSpec, facts); + if (discovery.store) this.discoveredStore = discovery.store; + for (const tpl of setupDirs) { + const path = interpolate(tpl, this.resolvedCtx); + await fs.ensureDirWritableAsync(path); + } + }; +} +``` + +with: + +```ts +if (setupDirs.length > 0 || requireFiles !== undefined) { + game.setup = async (discovery: IDiscoveryResult) => { + const { fs } = await import("vortex-api"); + const facts = this.factsFromDiscovery(discovery); + this.cachedFacts = facts; + this.resolvedCtx = resolveContext(contextSpec, facts); + if (discovery.store) this.discoveredStore = discovery.store; + for (const tpl of setupDirs) { + const path = interpolate(tpl, this.resolvedCtx); + await fs.ensureDirWritableAsync(path); + } + if (requireFiles !== undefined) { + await this.runRequireFilesCheck(requireFiles); + } + }; +} +``` + +- [ ] **Step 6: Add the `runRequireFilesCheck` method** + +Add this private method to the `GdlRuntime` class (e.g. just below `registerGame`): + +```ts + // Setup-time prerequisite check. Resolve each declared file template against + // the current context and stat it. If any are missing, show an informational + // dialog that points the user at a download. Non-fatal: it never rejects setup. + private async runRequireFilesCheck(spec: RequireFilesSpec): Promise { + const { fs, util } = await import('vortex-api'); + const ctx = this.resolvedCtx ?? ({} as ResolvedContext); + const resolved = spec.files.map((tpl) => interpolate(tpl, ctx)); + const present = await Promise.all( + resolved.map(async (p) => { + try { + await fs.statAsync(p); + return true; + } catch { + return false; + } + }), + ); + if (present.every(Boolean)) return; + + const actions: Array<{ label: string; action?: () => void }> = [{ label: 'Close' }]; + if (spec.prompt.link) { + const { label, url } = spec.prompt.link; + actions.push({ label, action: () => { void util.opn(url).catch(() => undefined); } }); + } + void this.api.api.showDialog('info', spec.prompt.title, { text: spec.prompt.message }, actions); + } +``` + +Note: `ResolvedContext` and `interpolate` are already imported at the top of this file. + +- [ ] **Step 7: Run to verify pass** + +Run: `cd game-description-language && pnpm exec vitest run tests/require-files.test.ts` +Expected: PASS (parser + validator + runtime). + +- [ ] **Step 8: Typecheck and commit** + +Run: `cd game-description-language && pnpm exec tsc --noEmit` +Expected: PASS. + +```bash +git -C game-description-language add src/runtime/vortex-shim.ts tests/require-files.test.ts +git -C game-description-language commit -m "feat(runtime): stat requireFiles and show download prompt in setup" +``` + +--- + +### Task A6: Codegen — emit the `requireFiles` literal + +**Files:** + +- Modify: `game-description-language/src/codegen/emit.ts` (build a literal near line 149; pass it as the 11th `registerGame` arg near line 264-267) +- Test: `game-description-language/tests/require-files.test.ts` (append) + +- [ ] **Step 1: Write the failing codegen tests** + +Append to `tests/require-files.test.ts`: + +```ts +import { emit } from "../src/codegen/emit.js"; + +describe("codegen: setup.requireFiles", () => { + const extOf = (yaml: string) => { + const doc = parseYaml(yaml, "rf.yaml"); + return emit(doc).find((f) => f.path.endsWith("extension.ts"))!.contents; + }; + + it("builds a nexus mod page URL from a mod target", () => { + const ext = extOf( + baseYaml( + ` files: + - \${installPath}/x.dll + prompt: + title: Action required + message: Install UMM + link: + label: Get UMM + mod: { domain: site, modId: 21 }`, + ), + ); + expect(ext).toContain("'https://www.nexusmods.com/site/mods/21'"); + expect(ext).toContain("Action required"); + }); + + it("passes a url target through unchanged", () => { + const ext = extOf( + baseYaml( + ` files: + - \${installPath}/x.dll + prompt: + title: T + message: M + link: + label: L + url: https://example.com/umm`, + ), + ); + expect(ext).toContain("'https://example.com/umm'"); + }); + + it("emits undefined when no requireFiles is declared", () => { + const ext = extOf(`gdl: 1 +game: + id: g + name: G + executable: G.exe + requiredFiles: [G.exe] +stores: + steam: "1" +setup: + ensureDirs: + - \${installPath}/Mods`); + // The 11th registerGame argument is the requireFiles literal. + expect(ext).toMatch(/\],\s*undefined,\s*\);/); + }); +}); +``` + +- [ ] **Step 2: Run to verify failure** + +Run: `cd game-description-language && pnpm exec vitest run tests/require-files.test.ts -t "codegen: setup.requireFiles"` +Expected: FAIL (no requireFiles arg emitted). + +- [ ] **Step 3: Build the literal** + +In `src/codegen/emit.ts`, after the `setupDirsLines` definition (around line 151), add: + +```ts +const requireFilesLit = (() => { + const rf = doc.setup?.requireFiles; + if (!rf) return "undefined"; + const filesLit = `[${rf.files.map(sq).join(", ")}]`; + let linkLit = ""; + if (rf.prompt.link) { + const t = rf.prompt.link.target; + const url = + t.kind === "url" ? t.url : `https://www.nexusmods.com/${t.domain}/mods/${t.modId}`; + linkLit = `, link: { label: ${sq(rf.prompt.link.label)}, url: ${sq(url)} }`; + } + return `{ files: ${filesLit}, prompt: { title: ${sq(rf.prompt.title)}, message: ${sq(rf.prompt.message)}${linkLit} } }`; +})(); +``` + +- [ ] **Step 4: Pass it as the 11th `registerGame` argument** + +In the `extension` template string, the `registerGame(...)` call currently ends with the diagnostics array: + +```ts + [ +${diagnosticsLines} + ], + ); +``` + +Change it to append the literal: + +```ts + [ +${diagnosticsLines} + ], + ${requireFilesLit}, + ); +``` + +- [ ] **Step 5: Run to verify pass** + +Run: `cd game-description-language && pnpm exec vitest run tests/require-files.test.ts` +Expected: PASS (all parser + validator + runtime + codegen cases). + +- [ ] **Step 6: Typecheck and commit** + +Run: `cd game-description-language && pnpm exec tsc --noEmit` + +```bash +git -C game-description-language add src/codegen/emit.ts tests/require-files.test.ts +git -C game-description-language commit -m "feat(codegen): emit setup.requireFiles into registerGame call" +``` + +--- + +### Task A7: Rebuild GDL dist and run the full suite + +**Files:** none (build + verify) + +- [ ] **Step 1: Full test suite** + +Run: `cd game-description-language && pnpm test` +Expected: PASS (baseline suite plus the new `require-files.test.ts` cases). No regressions. + +- [ ] **Step 2: Rebuild the toolchain dist** + +The Vortex game build reuses `game-description-language/dist` and only rebuilds it when `dist/cli.js` is absent. Rebuild it now so Phase B compiles against the new feature: + +```bash +cd game-description-language && pnpm build +``` + +Expected: build succeeds; `dist/cli.js`, `dist/commands/build.js` regenerated. + +- [ ] **Step 3: Confirm the branch is clean** + +Run: `git -C game-description-language status --porcelain` +Expected: empty (all feature changes committed; `dist/` is git-ignored in the submodule, confirm with `git -C game-description-language status` that no unexpected files are staged). + +--- + +# Phase B: Convert the two Pathfinder extensions + +All Phase B work is in the Vortex repo on branch `halgari/pathfinder-to-gdl` (already checked out). Run commands from `/c/oss/Vortex`. + +### Task B1: Convert Pathfinder: Kingmaker + +**Files:** + +- Create: `extensions/games/game-pathfinderkingmaker/game.yaml` +- Create: `extensions/games/game-pathfinderkingmaker/build.mjs` +- Create: `extensions/games/game-pathfinderkingmaker/vitest.config.ts` +- Rewrite: `extensions/games/game-pathfinderkingmaker/package.json` +- Move: `assets/gameart.jpg` to `gameart.jpg` (extension root) +- Delete: `src/index.js`, `assets/` (with `umm.png`), `tsconfig.tsbuildinfo` + +- [ ] **Step 1: Move the logo to the extension root and remove old files** + +Run: + +```bash +cd /c/oss/Vortex/extensions/games/game-pathfinderkingmaker +git mv assets/gameart.jpg gameart.jpg +git rm src/index.js assets/umm.png tsconfig.tsbuildinfo +rmdir assets 2>/dev/null || true +``` + +Expected: `gameart.jpg` now at the extension root; `src/`, `assets/` gone. + +- [ ] **Step 2: Write `game.yaml`** + +Create `extensions/games/game-pathfinderkingmaker/game.yaml`: + +```yaml +gdl: 1 +version: 0.2.0 + +game: + id: pathfinderkingmaker + name: "Pathfinder: Kingmaker" + executable: Kingmaker.exe + requiredFiles: [Kingmaker.exe] + logo: gameart.jpg + author: m0nster + nexusDomain: pathfinderkingmaker + # All Kingmaker mods deploy under the game's Mods folder (Unity Mod Manager). + queryModPath: Mods + +stores: + steam: "640820" + +setup: + ensureDirs: + - ${installPath}/Mods + requireFiles: + files: + - ${installPath}/UnityModManager/UnityModManager.dll + prompt: + title: Action required + message: >- + You must install Unity Mod Manager to use mods with Pathfinder: Kingmaker. + link: + label: Go to the Unity Mod Manager page + mod: { domain: site, modId: 21 } +``` + +- [ ] **Step 3: Write `build.mjs`** + +Create `extensions/games/game-pathfinderkingmaker/build.mjs` (identical to the X Rebirth GDL build entry): + +```js +import * as path from "node:path"; + +import { buildGdlExtension } from "../../../scripts/build-gdl-extension.mjs"; + +// This extension is described declaratively in game.yaml and compiled by the +// Game Description Language (GDL) toolchain into a Vortex-loadable dist/index.js. +await buildGdlExtension(path.resolve(import.meta.dirname)); +``` + +- [ ] **Step 4: Write `vitest.config.ts`** + +Create `extensions/games/game-pathfinderkingmaker/vitest.config.ts` (copied from X Rebirth so `pnpm test` runs cleanly even with no local tests): + +```ts +import { createRequire } from "node:module"; + +import { mergeConfig, defineConfig } from "vitest/config"; + +import baseConfig from "../../../vitest.base.config"; + +const require_ = createRequire(import.meta.url); +const VORTEX_API_MOCK = require_.resolve("@vortex/extension-test-mocks"); + +export default mergeConfig( + baseConfig, + defineConfig({ + resolve: { + alias: [{ find: /^@nexusmods\/vortex-api$/, replacement: VORTEX_API_MOCK }], + }, + test: { + environment: "node", + include: ["src/**/*.test.ts"], + }, + }), +); +``` + +- [ ] **Step 5: Rewrite `package.json`** + +Overwrite `extensions/games/game-pathfinderkingmaker/package.json`: + +```json +{ + "name": "game-pathfinderkingmaker", + "version": "0.2.0", + "description": "Support for Pathfinder: Kingmaker", + "scripts": { + "build": "node build.mjs", + "test": "pnpm exec vitest run --passWithNoTests" + }, + "author": "m0nster", + "license": "GPL-3.0", + "type": "commonjs", + "private": true, + "config": { + "game": "Pathfinder: Kingmaker" + }, + "devDependencies": { + "@nexusmods/vortex-api": "workspace:*", + "@vortex/extension-test-mocks": "workspace:*" + }, + "nx": { + "tags": ["vortex:extension"], + "targets": { + "build": { + "inputs": ["default", "typescript", "vortex-api"] + } + } + } +} +``` + +- [ ] **Step 6: Install workspace deps (new devDependency added)** + +Run (from `/c/oss/Vortex`): `pnpm install` +Expected: succeeds; links `@vortex/extension-test-mocks` into the package. + +- [ ] **Step 7: Build the extension** + +Run: `pnpm --filter game-pathfinderkingmaker run build` +Expected: GDL compiles `game.yaml`. Output: `dist/index.js`, `dist/index.js.map`, `dist/info.json`, `dist/gameart.jpg`. + +- [ ] **Step 8: Verify the build output** + +Run: + +```bash +ls extensions/games/game-pathfinderkingmaker/dist/ +cat extensions/games/game-pathfinderkingmaker/dist/info.json +grep -c "https://www.nexusmods.com/site/mods/21" extensions/games/game-pathfinderkingmaker/dist/index.js +``` + +Expected: `dist/` contains `index.js`, `info.json`, `gameart.jpg`; `info.json` has `id`/`name`/`version 0.2.0`; the grep prints `1` (the UMM page URL is baked into the bundle). + +- [ ] **Step 9: Run test + lint + format for the package** + +Run: + +```bash +pnpm --filter game-pathfinderkingmaker run test +pnpm exec eslint extensions/games/game-pathfinderkingmaker --max-warnings 0 || true +pnpm exec oxfmt extensions/games/game-pathfinderkingmaker +``` + +Expected: test passes with no test files (`--passWithNoTests`). Resolve any lint errors GDL extensions are expected to satisfy (the `|| true` is only to surface output; fix real errors). + +- [ ] **Step 10: Commit** + +```bash +cd /c/oss/Vortex +git add extensions/games/game-pathfinderkingmaker/ +git commit -m "Convert Pathfinder: Kingmaker extension to GDL + +Replace the imperative index.js with a declarative game.yaml. Drop the +modtype-umm dependency, registry probe, Bluebird, and platform guards. +UMM presence is checked via the new setup.requireFiles block, which prompts +the user to the Unity Mod Manager page when the loader is absent." +``` + +--- + +### Task B2: Convert Pathfinder: Wrath of the Righteous + +**Files:** + +- Create: `extensions/games/game-pathfinderwrathoftherighteous/game.yaml` +- Create: `extensions/games/game-pathfinderwrathoftherighteous/vitest.config.ts` +- Rewrite: `extensions/games/game-pathfinderwrathoftherighteous/build.mjs`, `package.json` +- Move: `assets/gameart.jpg` to `gameart.jpg` +- Delete: `src/index.ts`, `assets/` (with `umm.png`) + +- [ ] **Step 1: Move the logo and remove old files** + +Run: + +```bash +cd /c/oss/Vortex/extensions/games/game-pathfinderwrathoftherighteous +git mv assets/gameart.jpg gameart.jpg +git rm src/index.ts assets/umm.png +rmdir assets 2>/dev/null || true +``` + +- [ ] **Step 2: Write `game.yaml`** + +Create `extensions/games/game-pathfinderwrathoftherighteous/game.yaml`: + +```yaml +gdl: 1 +version: 1.0.1 + +game: + id: pathfinderwrathoftherighteous + name: "Pathfinder: Wrath of the Righteous" + executable: Wrath.exe + requiredFiles: [Wrath.exe] + logo: gameart.jpg + author: Black Tree Gaming Ltd. + nexusDomain: pathfinderwrathoftherighteous + queryModPath: Mods + +stores: + steam: "1184370" + gog: "1207187357" + +# Reads the build version from Version.info. The original extension split the +# file on spaces and took the 4th token; the regex captures that same token. +discovery: + version: + file: ${installPath}/Wrath_Data/StreamingAssets/Version.info + regex: '^(?:\S+\s+){3}(\S+)' + +setup: + ensureDirs: + - ${installPath}/Mods + requireFiles: + files: + - ${installPath}/UnityModManager/UnityModManager.dll + prompt: + title: Action required + message: >- + You must install Unity Mod Manager to use mods with Pathfinder: Wrath of + the Righteous. + link: + label: Go to the Unity Mod Manager page + mod: { domain: site, modId: 21 } +``` + +- [ ] **Step 3: Overwrite `build.mjs`** + +Replace `extensions/games/game-pathfinderwrathoftherighteous/build.mjs` with the GDL build entry: + +```js +import * as path from "node:path"; + +import { buildGdlExtension } from "../../../scripts/build-gdl-extension.mjs"; + +// This extension is described declaratively in game.yaml and compiled by the +// Game Description Language (GDL) toolchain into a Vortex-loadable dist/index.js. +await buildGdlExtension(path.resolve(import.meta.dirname)); +``` + +- [ ] **Step 4: Write `vitest.config.ts`** + +Create `extensions/games/game-pathfinderwrathoftherighteous/vitest.config.ts` with the same contents as Task B1 Step 4. + +- [ ] **Step 5: Rewrite `package.json`** + +Overwrite `extensions/games/game-pathfinderwrathoftherighteous/package.json`: + +```json +{ + "name": "game-pathfinderwrathoftherighteous", + "version": "1.0.1", + "description": "Support for Pathfinder: Wrath of the Righteous", + "scripts": { + "build": "node build.mjs", + "test": "pnpm exec vitest run --passWithNoTests" + }, + "author": "Black Tree Gaming Ltd.", + "license": "GPL-3.0", + "type": "commonjs", + "private": true, + "config": { + "game": "Pathfinder: Wrath of the Righteous" + }, + "devDependencies": { + "@nexusmods/vortex-api": "workspace:*", + "@vortex/extension-test-mocks": "workspace:*" + }, + "nx": { + "tags": ["vortex:extension"], + "targets": { + "build": { + "inputs": ["default", "typescript", "vortex-api"] + } + } + } +} +``` + +- [ ] **Step 6: Install, build, verify** + +Run (from `/c/oss/Vortex`): + +```bash +pnpm install +pnpm --filter game-pathfinderwrathoftherighteous run build +ls extensions/games/game-pathfinderwrathoftherighteous/dist/ +cat extensions/games/game-pathfinderwrathoftherighteous/dist/info.json +grep -c "https://www.nexusmods.com/site/mods/21" extensions/games/game-pathfinderwrathoftherighteous/dist/index.js +``` + +Expected: `dist/index.js`, `dist/info.json` (version `1.0.1`), `dist/gameart.jpg`; grep prints `1`. Confirm the bundle also references `Version.info` (the version regex): `grep -c "Version.info" .../dist/index.js` prints `1`. + +- [ ] **Step 7: Test + lint + format** + +Run: + +```bash +pnpm --filter game-pathfinderwrathoftherighteous run test +pnpm exec oxfmt extensions/games/game-pathfinderwrathoftherighteous +``` + +Expected: test passes (`--passWithNoTests`); format clean. + +- [ ] **Step 8: Commit** + +```bash +git add extensions/games/game-pathfinderwrathoftherighteous/ +git commit -m "Convert Pathfinder: Wrath of the Righteous extension to GDL + +Replace the imperative index.ts with a declarative game.yaml. Drop the +modtype-umm/ummAddGame integration, move version detection to a declarative +discovery.version (Version.info) block, and add the setup.requireFiles UMM +prompt. WotR no longer auto-downloads UMM (accepted regression)." +``` + +--- + +### Task B3: Bump the submodule pointer and final verification + +**Files:** + +- Modify: the `game-description-language` submodule gitlink (Vortex records the new commit) + +- [ ] **Step 1: Stage the submodule pointer** + +The Vortex working tree now sees `game-description-language` at the new `feat/setup-require-files` commit. Stage it: + +```bash +cd /c/oss/Vortex +git add game-description-language +git status +``` + +Expected: `game-description-language` shows as a modified submodule (new commit). + +- [ ] **Step 2: Rebuild both games against the bumped submodule from a clean dist** + +Run: + +```bash +rm -rf extensions/games/game-pathfinderkingmaker/dist extensions/games/game-pathfinderwrathoftherighteous/dist +pnpm --filter game-pathfinderkingmaker run build +pnpm --filter game-pathfinderwrathoftherighteous run build +``` + +Expected: both build cleanly against the current submodule dist. + +- [ ] **Step 3: Commit the submodule bump** + +```bash +git commit -m "chore: bump game-description-language submodule for setup.requireFiles" +``` + +- [ ] **Step 4: Final affected-package checks** + +Run: + +```bash +pnpm --filter game-pathfinderkingmaker run test +pnpm --filter game-pathfinderwrathoftherighteous run test +pnpm exec oxfmt extensions/games/game-pathfinderkingmaker extensions/games/game-pathfinderwrathoftherighteous +``` + +Expected: all green. + +- [ ] **Step 5: Independent review (recommended)** + +Spawn a review subagent (clean context, sonnet) to verify each `game.yaml` is a faithful replacement of the original discovery paths (Steam/GOG ids, exe, Mods path, WotR version source) and that the dropped behaviors match the approved design. Fix anything it surfaces before opening a PR. + +--- + +## Notes for the implementer + +- The GDL feature lives in a separate repo (`Nexus-Mods/game-description-language`). Pushing `feat/setup-require-files` and opening its PR is a separate step from this plan; the Vortex branch only records the submodule commit. Do not push or open PRs unless asked. +- `buildGdlExtension` caches the submodule build. If a game build ever picks up stale GDL behavior, rebuild the submodule dist: `cd game-description-language && pnpm build`. +- The UMM marker path `${installPath}/UnityModManager/UnityModManager.dll` is a best-effort path-based check. Verify it against a real UMM-patched Pathfinder install; the value is a one-line `game.yaml` edit. +- Keep `game.yaml`'s `version:` in sync with `package.json`. The build steps assert the emitted `info.json` version (0.2.0 / 1.0.1); if it comes out as `0.0.0`, trace how `build.ts` sources `extensionVersion` and adjust (mirror what X Rebirth does, which sets both). From 5cb88c847a0479582461fca0d523b0374b681df9 Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Wed, 17 Jun 2026 19:16:33 -0700 Subject: [PATCH 3/9] Convert Pathfinder: Kingmaker extension to GDL Replace the imperative index.js with a declarative game.yaml. Drop the modtype-umm dependency, registry probe, Bluebird, and platform guards. UMM presence is checked via the new setup.requireFiles block, which prompts the user to the Unity Mod Manager page when the loader is absent. --- .../game-pathfinderkingmaker/assets/umm.png | Bin 1965 -> 0 bytes .../games/game-pathfinderkingmaker/build.mjs | 7 ++ .../games/game-pathfinderkingmaker/game.yaml | 30 ++++++ .../{assets => }/gameart.jpg | Bin .../game-pathfinderkingmaker/package.json | 7 +- .../game-pathfinderkingmaker/src/index.js | 94 ------------------ .../game-pathfinderkingmaker/vitest.config.ts | 21 ++++ pnpm-lock.yaml | 3 + 8 files changed, 65 insertions(+), 97 deletions(-) delete mode 100644 extensions/games/game-pathfinderkingmaker/assets/umm.png create mode 100644 extensions/games/game-pathfinderkingmaker/build.mjs create mode 100644 extensions/games/game-pathfinderkingmaker/game.yaml rename extensions/games/game-pathfinderkingmaker/{assets => }/gameart.jpg (100%) delete mode 100644 extensions/games/game-pathfinderkingmaker/src/index.js create mode 100644 extensions/games/game-pathfinderkingmaker/vitest.config.ts diff --git a/extensions/games/game-pathfinderkingmaker/assets/umm.png b/extensions/games/game-pathfinderkingmaker/assets/umm.png deleted file mode 100644 index 88088e674bc71270c95b6980adb4cd654d0b03e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1965 zcmV;e2U7TnP)004R= z004l4008;_004mL004C`008P>0026e000+nl3&F}00009a7bBm000XT000XT0n*)m z`~Uy|7<5HgbW?9;ba!ELWdLwtX>N2bZe?^JG%hhNHDpIvQUCx44@pEpR9HvtSNT&@ zR}}7FQ*CQ)r_-5Er&Bvx*V1Z7+nH(?tE`F(3e<&yA}EMd*^C857!iT6$(kUMEkFbb zND=}eBq7TqKu8Dy0$J&KxtGUFc+pNL&h!VrIg@$!ocr$i?z!il^YYH>{{wG%c;k)m z&`ueOYFkvq6dIZ=3+Uk$2qX{vtjXne!vm+gKlp0Ko#Gmeer8})5uTh~#p^{?cJYmZD#Od5;|?PL@G#fj@V6rmTxWB3Jc1b~OxYK_19Fy>AHxQR;3 z)lJW0!x{{8^Ov)VzU5#!M`N?^ zJ{~&OszgJP(HhdO9GqQ3Lkg`ghQJ4;0vE`|h*eDJ86snLznW`Vv|<$v zzC3u^dGG|Xxs?26l+*kPyK8+z6)pVa{8I37ySRGeMkxRTlIwG3uD(3j3e%=i5#8(7 za`6{6(oHlC$gwtM@!0H{F7>d9+??IvJe!saZu+Hiw2lvC6GUiYCQJxP%p6uRP(hv{0 zR#@vnd2=VYgpfehg0cqBr&I4WboLfEwgN?i+3)t&d3;hKK|Ht`GgA5kB*d3%iL$Rz z7T>2M7VXH?+#`f$J2a*;nk|L3JmAs5?*lztBgV9#K=K%$Ur81cXkC!eIls}P0Of?5 z55l2Qr-Bbun!5U@jj!1i0?C7l1QMT6Gva8g5>1Aq+0PlZK#Z)6AbBi1 z-P%RlPEQF3$rj`9N`IJKvVTy9d3O*Ntfe6_=fU=)XAeYPPRV<8CFjA{$Iij<36GD> zOu%^xfI5bjh61X$;=E%-RF@jf1i3w=N8uk=>*BKt#x;|V8(O{ziv`C%@^fsGbbO+u z{%K23zh@aQtn+{ssnvgdrhqzu4c>rn04TN8OlSg7;6a~LQVq^_9w)c%Pj-3&vpXbu z)-;D!qkwrpo29P~a*!(*8@+DYoXwg3Qcq2T?A~5G@-bUXERn$zyp&M>cKjX{ekHx2 zvhkTf*w`*ee^C0v*?7vDnpc7rqyzIXt~i3*lote=_&zN?XQA&$cdIWw*ZlTOv1KhM zKp;=Y%*#*}Y)(i-H~d{FtZG1RLKD)Uru#Hro6TO%X+_ZrOSm;}vG`0_KNkvusYRcb zyHTQh)_Z0?yZ+mV3n=E_ow#VW_`Pndk}AaY(3$unu}K<2j}6Q`rWcX3E#+b;50r0c zev$l%phmL%e^xb2eY3@+vfv<)19tPP{-;RfN;C}wUg7e4v4N2Xw2x0KCEK2is26M? zdD0nh{1ICWX9w1Kn=`4Opw~JmQ@Q1}X!Q|=8f%&0a=G?-uF|gH^X+|uFvJE%9sua? zdQbKN%r++^V?>7v4H?naJAioTrVLoc1jq@LutDK}EO@sYW*$C(!sYK81FS16nZ=ce z$EctG4G2^`_JqX9yuZr+6^~cr%#BP$0;Go5iM31^maC|ldqSf5LJ>9ughy_9-S?;B zb{#(ttHXn3(YNPO$Y<9f5|AHzLt_*=0viIt1EOuS+wT;WBOh@Y_m`F#I<{O*fNz)( z6n=r2o`KV(7mxt(Ku@9<5CYtC!&5!N%YOT^c#y1Fdq38^$>RG@=#LgUg;8cB^@#&I4*VLH)6neIGj%X z4B2>R=gdc95`7qe- + You must install Unity Mod Manager to use mods with Pathfinder: Kingmaker. + link: + label: Go to the Unity Mod Manager page + mod: { domain: site, modId: 21 } diff --git a/extensions/games/game-pathfinderkingmaker/assets/gameart.jpg b/extensions/games/game-pathfinderkingmaker/gameart.jpg similarity index 100% rename from extensions/games/game-pathfinderkingmaker/assets/gameart.jpg rename to extensions/games/game-pathfinderkingmaker/gameart.jpg diff --git a/extensions/games/game-pathfinderkingmaker/package.json b/extensions/games/game-pathfinderkingmaker/package.json index f1a00bf164..83601e39f1 100644 --- a/extensions/games/game-pathfinderkingmaker/package.json +++ b/extensions/games/game-pathfinderkingmaker/package.json @@ -3,8 +3,8 @@ "version": "0.2.0", "description": "Support for Pathfinder: Kingmaker", "scripts": { - "_assets": "copyfiles -u 1 -f ./assets/* dist", - "build": "copyfiles -u 1 -f ./src/index.js dist && pnpm run _assets && pnpm extractInfo" + "build": "node build.mjs", + "test": "pnpm exec vitest run --passWithNoTests" }, "author": "m0nster", "license": "GPL-3.0", @@ -14,7 +14,8 @@ "game": "Pathfinder: Kingmaker" }, "devDependencies": { - "@nexusmods/vortex-api": "workspace:*" + "@nexusmods/vortex-api": "workspace:*", + "@vortex/extension-test-mocks": "workspace:*" }, "nx": { "tags": [ diff --git a/extensions/games/game-pathfinderkingmaker/src/index.js b/extensions/games/game-pathfinderkingmaker/src/index.js deleted file mode 100644 index bf5f149734..0000000000 --- a/extensions/games/game-pathfinderkingmaker/src/index.js +++ /dev/null @@ -1,94 +0,0 @@ -const Promise = require("bluebird"); -const path = require("path"); -const winapi = require("winapi-bindings"); -const { actions, fs, util } = require("@nexusmods/vortex-api"); - -const IsWin = process.platform === "win32"; - -const NexusId = "pathfinderkingmaker"; -const Name = "Pathfinder:\tKingmaker"; -const ExeName = "Kingmaker"; -const SteamId = 640820; - -const UMM_DLL = "UnityModManager.dll"; - -function main(context) { - context.requireExtension("modtype-umm"); - context.registerGame({ - id: NexusId, - name: Name, - logo: "gameart.jpg", - mergeMods: true, - queryPath: findGame, - queryModPath: () => "Mods", - executable: () => ExeName + ".exe", - requiredFiles: [ExeName + ".exe"], - environment: { - SteamAPPId: SteamId.toString(), - }, - details: { - steamAppId: SteamId, - }, - setup: setup, - }); - - function findGame() { - return util.steam.findByAppId(SteamId.toString()).then((game) => game.gamePath); - } - - function readRegistryKey(hive, key, name) { - if (!IsWin) { - return Promise.reject(new util.UnsupportedOperatingSystem()); - } - - try { - const instPath = winapi.RegGetValue(hive, key, name); - if (!instPath) { - throw new Error("empty registry key"); - } - return Promise.resolve(instPath.value); - } catch (err) { - return Promise.reject(new util.ProcessCanceled(err)); - } - } - - function findUnityModManager() { - return readRegistryKey("HKEY_CURRENT_USER", "Software\\UnityModManager", "Path").then((value) => - fs.statAsync(path.join(value, UMM_DLL)), - ); - } - - function setup(discovery) { - return fs - .ensureDirWritableAsync(path.join(discovery.path, "Mods"), () => Promise.resolve()) - .then(() => - findUnityModManager().catch((err) => { - return new Promise((resolve, reject) => { - context.api.store.dispatch( - actions.showDialog( - "question", - "Action required", - { message: "You must install Unity Mod Manager to use mods with " + Name + "." }, - [ - { label: "Cancel", action: () => reject(new util.UserCanceled()) }, - { - label: "Go to the Unity Mod Manager page", - action: () => { - util.opn("https://www.nexusmods.com/site/mods/21/").catch((err) => undefined); - reject(new util.UserCanceled()); - }, - }, - ], - ), - ); - }); - }), - ); - } - - return true; -} - -module.exports = { - default: main, -}; diff --git a/extensions/games/game-pathfinderkingmaker/vitest.config.ts b/extensions/games/game-pathfinderkingmaker/vitest.config.ts new file mode 100644 index 0000000000..cd502d99fb --- /dev/null +++ b/extensions/games/game-pathfinderkingmaker/vitest.config.ts @@ -0,0 +1,21 @@ +import { createRequire } from "node:module"; + +import { mergeConfig, defineConfig } from "vitest/config"; + +import baseConfig from "../../../vitest.base.config"; + +const require_ = createRequire(import.meta.url); +const VORTEX_API_MOCK = require_.resolve("@vortex/extension-test-mocks"); + +export default mergeConfig( + baseConfig, + defineConfig({ + resolve: { + alias: [{ find: /^@nexusmods\/vortex-api$/, replacement: VORTEX_API_MOCK }], + }, + test: { + environment: "node", + include: ["src/**/*.test.ts"], + }, + }), +); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e1bd2dbbe9..c207eb6d85 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2309,6 +2309,9 @@ importers: '@nexusmods/vortex-api': specifier: workspace:* version: link:../../../packages/vortex-api + '@vortex/extension-test-mocks': + specifier: workspace:* + version: link:../../../packages/extension-test-mocks extensions/games/game-pathfinderwrathoftherighteous: devDependencies: From c2e706022811e2e1b770a77d29e3f119cca04e2e Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Wed, 17 Jun 2026 19:23:53 -0700 Subject: [PATCH 4/9] Convert Pathfinder: Wrath of the Righteous extension to GDL Replace the imperative index.ts with a declarative game.yaml. Drop the modtype-umm/ummAddGame integration, move version detection to a declarative discovery.version (Version.info) block, and add the setup.requireFiles UMM prompt. WotR no longer auto-downloads UMM (accepted regression). --- .../assets/umm.png | Bin 1965 -> 0 bytes .../build.mjs | 11 ++- .../game.yaml | 38 +++++++++++ .../{assets => }/gameart.jpg | Bin .../package.json | 7 +- .../src/index.ts | 64 ------------------ .../vitest.config.ts | 21 ++++++ 7 files changed, 67 insertions(+), 74 deletions(-) delete mode 100644 extensions/games/game-pathfinderwrathoftherighteous/assets/umm.png create mode 100644 extensions/games/game-pathfinderwrathoftherighteous/game.yaml rename extensions/games/game-pathfinderwrathoftherighteous/{assets => }/gameart.jpg (100%) delete mode 100644 extensions/games/game-pathfinderwrathoftherighteous/src/index.ts create mode 100644 extensions/games/game-pathfinderwrathoftherighteous/vitest.config.ts diff --git a/extensions/games/game-pathfinderwrathoftherighteous/assets/umm.png b/extensions/games/game-pathfinderwrathoftherighteous/assets/umm.png deleted file mode 100644 index 88088e674bc71270c95b6980adb4cd654d0b03e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1965 zcmV;e2U7TnP)004R= z004l4008;_004mL004C`008P>0026e000+nl3&F}00009a7bBm000XT000XT0n*)m z`~Uy|7<5HgbW?9;ba!ELWdLwtX>N2bZe?^JG%hhNHDpIvQUCx44@pEpR9HvtSNT&@ zR}}7FQ*CQ)r_-5Er&Bvx*V1Z7+nH(?tE`F(3e<&yA}EMd*^C857!iT6$(kUMEkFbb zND=}eBq7TqKu8Dy0$J&KxtGUFc+pNL&h!VrIg@$!ocr$i?z!il^YYH>{{wG%c;k)m z&`ueOYFkvq6dIZ=3+Uk$2qX{vtjXne!vm+gKlp0Ko#Gmeer8})5uTh~#p^{?cJYmZD#Od5;|?PL@G#fj@V6rmTxWB3Jc1b~OxYK_19Fy>AHxQR;3 z)lJW0!x{{8^Ov)VzU5#!M`N?^ zJ{~&OszgJP(HhdO9GqQ3Lkg`ghQJ4;0vE`|h*eDJ86snLznW`Vv|<$v zzC3u^dGG|Xxs?26l+*kPyK8+z6)pVa{8I37ySRGeMkxRTlIwG3uD(3j3e%=i5#8(7 za`6{6(oHlC$gwtM@!0H{F7>d9+??IvJe!saZu+Hiw2lvC6GUiYCQJxP%p6uRP(hv{0 zR#@vnd2=VYgpfehg0cqBr&I4WboLfEwgN?i+3)t&d3;hKK|Ht`GgA5kB*d3%iL$Rz z7T>2M7VXH?+#`f$J2a*;nk|L3JmAs5?*lztBgV9#K=K%$Ur81cXkC!eIls}P0Of?5 z55l2Qr-Bbun!5U@jj!1i0?C7l1QMT6Gva8g5>1Aq+0PlZK#Z)6AbBi1 z-P%RlPEQF3$rj`9N`IJKvVTy9d3O*Ntfe6_=fU=)XAeYPPRV<8CFjA{$Iij<36GD> zOu%^xfI5bjh61X$;=E%-RF@jf1i3w=N8uk=>*BKt#x;|V8(O{ziv`C%@^fsGbbO+u z{%K23zh@aQtn+{ssnvgdrhqzu4c>rn04TN8OlSg7;6a~LQVq^_9w)c%Pj-3&vpXbu z)-;D!qkwrpo29P~a*!(*8@+DYoXwg3Qcq2T?A~5G@-bUXERn$zyp&M>cKjX{ekHx2 zvhkTf*w`*ee^C0v*?7vDnpc7rqyzIXt~i3*lote=_&zN?XQA&$cdIWw*ZlTOv1KhM zKp;=Y%*#*}Y)(i-H~d{FtZG1RLKD)Uru#Hro6TO%X+_ZrOSm;}vG`0_KNkvusYRcb zyHTQh)_Z0?yZ+mV3n=E_ow#VW_`Pndk}AaY(3$unu}K<2j}6Q`rWcX3E#+b;50r0c zev$l%phmL%e^xb2eY3@+vfv<)19tPP{-;RfN;C}wUg7e4v4N2Xw2x0KCEK2is26M? zdD0nh{1ICWX9w1Kn=`4Opw~JmQ@Q1}X!Q|=8f%&0a=G?-uF|gH^X+|uFvJE%9sua? zdQbKN%r++^V?>7v4H?naJAioTrVLoc1jq@LutDK}EO@sYW*$C(!sYK81FS16nZ=ce z$EctG4G2^`_JqX9yuZr+6^~cr%#BP$0;Go5iM31^maC|ldqSf5LJ>9ughy_9-S?;B zb{#(ttHXn3(YNPO$Y<9f5|AHzLt_*=0viIt1EOuS+wT;WBOh@Y_m`F#I<{O*fNz)( z6n=r2o`KV(7mxt(Ku@9<5CYtC!&5!N%YOT^c#y1Fdq38^$>RG@=#LgUg;8cB^@#&I4*VLH)6neIGj%X z4B2>R=gdc95`7qe- + You must install Unity Mod Manager to use mods with Pathfinder: Wrath of + the Righteous. + link: + label: Go to the Unity Mod Manager page + mod: { domain: site, modId: 21 } diff --git a/extensions/games/game-pathfinderwrathoftherighteous/assets/gameart.jpg b/extensions/games/game-pathfinderwrathoftherighteous/gameart.jpg similarity index 100% rename from extensions/games/game-pathfinderwrathoftherighteous/assets/gameart.jpg rename to extensions/games/game-pathfinderwrathoftherighteous/gameart.jpg diff --git a/extensions/games/game-pathfinderwrathoftherighteous/package.json b/extensions/games/game-pathfinderwrathoftherighteous/package.json index 6f3334ed57..e3d61dee02 100644 --- a/extensions/games/game-pathfinderwrathoftherighteous/package.json +++ b/extensions/games/game-pathfinderwrathoftherighteous/package.json @@ -3,8 +3,8 @@ "version": "1.0.1", "description": "Support for Pathfinder: Wrath of the Righteous", "scripts": { - "_assets": "copyfiles -u 1 -f ./assets/* dist", - "build": "node build.mjs && pnpm run _assets && pnpm extractInfo" + "build": "node build.mjs", + "test": "pnpm exec vitest run --passWithNoTests" }, "author": "Black Tree Gaming Ltd.", "license": "GPL-3.0", @@ -14,7 +14,8 @@ "game": "Pathfinder: Wrath of the Righteous" }, "devDependencies": { - "@nexusmods/vortex-api": "workspace:*" + "@nexusmods/vortex-api": "workspace:*", + "@vortex/extension-test-mocks": "workspace:*" }, "nx": { "tags": [ diff --git a/extensions/games/game-pathfinderwrathoftherighteous/src/index.ts b/extensions/games/game-pathfinderwrathoftherighteous/src/index.ts deleted file mode 100644 index 0165fb7a45..0000000000 --- a/extensions/games/game-pathfinderwrathoftherighteous/src/index.ts +++ /dev/null @@ -1,64 +0,0 @@ -const path = require("path"); -const { fs, types, util } = require("@nexusmods/vortex-api"); - -const GAME_ID = "pathfinderwrathoftherighteous"; -const NAME = "Pathfinder: Wrath\tof the Righteous"; -const STEAM_ID = "1184370"; -const GOG_ID = "1207187357"; - -function findGame() { - return util.GameStoreHelper.findByAppId([STEAM_ID, GOG_ID]).then((game) => game.gamePath); -} - -function setup(discovery) { - return fs.ensureDirWritableAsync(path.join(discovery.path, "Mods")); -} - -async function resolveGameVersion(discoveryPath: string) { - const versionFilepath = path.join(discoveryPath, "Wrath_Data", "StreamingAssets", "Version.info"); - try { - const data = await fs.readFileAsync(versionFilepath, { encoding: "utf8" }); - const segments = data.split(" "); - return segments[3] - ? Promise.resolve(segments[3]) - : Promise.reject(new util.DataInvalid("Failed to resolve version")); - } catch (err) { - return Promise.reject(err); - } -} - -function main(context) { - context.requireExtension("modtype-umm"); - context.registerGame({ - id: GAME_ID, - name: NAME, - logo: "gameart.jpg", - mergeMods: true, - queryPath: findGame, - queryModPath: () => "Mods", - executable: () => "Wrath.exe", - getGameVersion: resolveGameVersion, - requiredFiles: ["Wrath.exe"], - environment: { - SteamAPPId: STEAM_ID, - }, - details: { - steamAppId: +STEAM_ID, - }, - setup, - }); - context.once(() => { - if (context.api.ext.ummAddGame !== undefined) { - context.api.ext.ummAddGame({ - gameId: GAME_ID, - autoDownloadUMM: true, - }); - } - }); - - return true; -} - -module.exports = { - default: main, -}; diff --git a/extensions/games/game-pathfinderwrathoftherighteous/vitest.config.ts b/extensions/games/game-pathfinderwrathoftherighteous/vitest.config.ts new file mode 100644 index 0000000000..cd502d99fb --- /dev/null +++ b/extensions/games/game-pathfinderwrathoftherighteous/vitest.config.ts @@ -0,0 +1,21 @@ +import { createRequire } from "node:module"; + +import { mergeConfig, defineConfig } from "vitest/config"; + +import baseConfig from "../../../vitest.base.config"; + +const require_ = createRequire(import.meta.url); +const VORTEX_API_MOCK = require_.resolve("@vortex/extension-test-mocks"); + +export default mergeConfig( + baseConfig, + defineConfig({ + resolve: { + alias: [{ find: /^@nexusmods\/vortex-api$/, replacement: VORTEX_API_MOCK }], + }, + test: { + environment: "node", + include: ["src/**/*.test.ts"], + }, + }), +); From 81f9512bef7fea666bcbe98c330ce4d06b6a012e Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Wed, 17 Jun 2026 19:29:18 -0700 Subject: [PATCH 5/9] chore: bump game-description-language submodule for setup.requireFiles Records the GDL submodule at the setup.requireFiles feature commit, which the two Pathfinder game extensions depend on. Also commits the lockfile change for the @vortex/extension-test-mocks devDependency the converted games added. --- game-description-language | 2 +- pnpm-lock.yaml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/game-description-language b/game-description-language index b1aab385ef..3aea0ea923 160000 --- a/game-description-language +++ b/game-description-language @@ -1 +1 @@ -Subproject commit b1aab385efbc4a81de1692db1b423c9d6b178346 +Subproject commit 3aea0ea923895f089d90a4e5934f8ee4332e205e diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c207eb6d85..2d3d9f3b15 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2318,6 +2318,9 @@ importers: '@nexusmods/vortex-api': specifier: workspace:* version: link:../../../packages/vortex-api + '@vortex/extension-test-mocks': + specifier: workspace:* + version: link:../../../packages/extension-test-mocks extensions/games/game-pillarsofeternity2: devDependencies: From 1be6e9f62223223998b923d82900b3a93f93add6 Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Wed, 17 Jun 2026 20:09:38 -0700 Subject: [PATCH 6/9] Add portrait mod type and installers to Pathfinder extensions Character portraits deploy to the user's LocalLow Owlcat profile, not the game's Mods folder. A portrait folder is recognised by the Small + Medium + Fulllength PNG trio. Two installers route them: portrait-collection strips a top-level Portraits/ wrapper for multi-portrait packs, and portrait takes a single portrait folder. UMM code mods (.dll) and in-game asset-bundle replacements are excluded so they keep their existing deployment. Also enable corpus testing (tests.corpus: nexus), now that the extensions have installer rules worth exercising. Verified against the live Nexus corpus: 85 of 247 Kingmaker mods and 106 of 235 WotR mods route to the portrait types, with zero failures and the excluded shapes correctly left to default. --- .../games/game-pathfinderkingmaker/game.yaml | 55 ++++++++++++++++++- .../game.yaml | 54 ++++++++++++++++++ 2 files changed, 108 insertions(+), 1 deletion(-) diff --git a/extensions/games/game-pathfinderkingmaker/game.yaml b/extensions/games/game-pathfinderkingmaker/game.yaml index c109b9a03e..0076930808 100644 --- a/extensions/games/game-pathfinderkingmaker/game.yaml +++ b/extensions/games/game-pathfinderkingmaker/game.yaml @@ -9,12 +9,62 @@ game: logo: gameart.jpg author: m0nster nexusDomain: pathfinderkingmaker - # All Kingmaker mods deploy under the game's Mods folder (Unity Mod Manager). + # Unity Mod Manager mods deploy under the game's Mods folder. queryModPath: Mods stores: steam: "640820" +context: + # Custom character portraits live in the user's LocalLow profile, not the game + # install. Each portrait is a folder of Small/Medium/Fulllength PNGs. + portraitsRoot: ${appDataLocalLow}/Owlcat Games/Pathfinder Kingmaker/Portraits + +modTypes: + - { id: portrait, name: Portrait, path: "${portraitsRoot}" } + +# A portrait folder is identified by the Small + Medium + Fulllength PNG trio. +# UMM code mods (.dll) and in-game asset-bundle replacements are excluded so they +# keep deploying to Mods/ and the game data folder respectively. +installers: + # Multi-portrait packs wrapped in a top-level Portraits/ folder: strip the + # wrapper so each portrait subfolder lands directly under the Portraits root. + - id: portrait-collection + priority: 24 + when: + all: + - { hasFile: "**/Portraits/*/Fulllength.png" } + - { hasFile: "**/Portraits/*/Medium.png" } + - { hasFile: "**/Portraits/*/Small.png" } + unless: + any: + - { hasFile: "**/*.dll" } + - { hasFile: "**/*_Data/StreamingAssets/**" } + copy: { stripCommonRoot: true } + modType: portrait + + # A single portrait in its own folder: take that folder and place it under the + # Portraits root. + - id: portrait + priority: 25 + when: + all: + - { hasFile: "**/Fulllength.png" } + - { hasFile: "**/Medium.png" } + - { hasFile: "**/Small.png" } + unless: + any: + - { hasFile: "**/*.dll" } + - { hasFile: "**/*_Data/StreamingAssets/**" } + # Root-loose portraits have no folder name to deploy into; out of scope. + - { hasFile: "Fulllength.png" } + # Wrapped packs are handled by portrait-collection above. + - { hasFile: "**/Portraits/*/Fulllength.png" } + anchor: "**/Fulllength.png" + take: parent + placeAt: ${portraitsRoot} + modType: portrait + setup: ensureDirs: - ${installPath}/Mods @@ -28,3 +78,6 @@ setup: link: label: Go to the Unity Mod Manager page mod: { domain: site, modId: 21 } + +tests: + corpus: nexus diff --git a/extensions/games/game-pathfinderwrathoftherighteous/game.yaml b/extensions/games/game-pathfinderwrathoftherighteous/game.yaml index c7fe0fbdb6..f662771d0a 100644 --- a/extensions/games/game-pathfinderwrathoftherighteous/game.yaml +++ b/extensions/games/game-pathfinderwrathoftherighteous/game.yaml @@ -9,12 +9,21 @@ game: logo: gameart.jpg author: Black Tree Gaming Ltd. nexusDomain: pathfinderwrathoftherighteous + # Unity Mod Manager mods deploy under the game's Mods folder. queryModPath: Mods stores: steam: "1184370" gog: "1207187357" +context: + # Custom character portraits live in the user's LocalLow profile, not the game + # install. Each portrait is a folder of Small/Medium/Fulllength PNGs. + portraitsRoot: ${appDataLocalLow}/Owlcat Games/Pathfinder Wrath Of The Righteous/Portraits + +modTypes: + - { id: portrait, name: Portrait, path: "${portraitsRoot}" } + # Reads the build version from Version.info. The original extension split the # file on spaces and took the 4th token; the regex captures that same token. discovery: @@ -22,6 +31,48 @@ discovery: file: ${installPath}/Wrath_Data/StreamingAssets/Version.info regex: '^(?:\S+\s+){3}(\S+)' +# A portrait folder is identified by the Small + Medium + Fulllength PNG trio. +# UMM code mods (.dll) and in-game asset-bundle replacements are excluded so they +# keep deploying to Mods/ and the game data folder respectively. +installers: + # Multi-portrait packs wrapped in a top-level Portraits/ folder: strip the + # wrapper so each portrait subfolder lands directly under the Portraits root. + - id: portrait-collection + priority: 24 + when: + all: + - { hasFile: "**/Portraits/*/Fulllength.png" } + - { hasFile: "**/Portraits/*/Medium.png" } + - { hasFile: "**/Portraits/*/Small.png" } + unless: + any: + - { hasFile: "**/*.dll" } + - { hasFile: "**/*_Data/StreamingAssets/**" } + copy: { stripCommonRoot: true } + modType: portrait + + # A single portrait in its own folder: take that folder and place it under the + # Portraits root. + - id: portrait + priority: 25 + when: + all: + - { hasFile: "**/Fulllength.png" } + - { hasFile: "**/Medium.png" } + - { hasFile: "**/Small.png" } + unless: + any: + - { hasFile: "**/*.dll" } + - { hasFile: "**/*_Data/StreamingAssets/**" } + # Root-loose portraits have no folder name to deploy into; out of scope. + - { hasFile: "Fulllength.png" } + # Wrapped packs are handled by portrait-collection above. + - { hasFile: "**/Portraits/*/Fulllength.png" } + anchor: "**/Fulllength.png" + take: parent + placeAt: ${portraitsRoot} + modType: portrait + setup: ensureDirs: - ${installPath}/Mods @@ -36,3 +87,6 @@ setup: link: label: Go to the Unity Mod Manager page mod: { domain: site, modId: 21 } + +tests: + corpus: nexus From 8d9b66453c15989a79a600eb581ef2c3d25a8190 Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Wed, 17 Jun 2026 22:57:40 -0700 Subject: [PATCH 7/9] Add full portrait coverage and voice routing to Pathfinder extensions Reintroduce src/hooks.ts with two install hooks: - installPortrait deploys every portrait folder (the Small/Medium/Fulllength PNG trio) as Portraits// under the user's LocalLow profile. One hook covers single-folder, multi-portrait Portraits/ wrappers, and loose-at-root archives (synthesising a folder name) at any nesting depth, replacing the earlier declarative portrait installers. - installVoice flattens Wwise .bnk soundbanks into the game's audio folder via a new voice mod type. Packs bundling multiple variants of the same bank deploy to Mods/ unchanged, since an installer cannot pick a variant. Verified against the live Nexus corpus with zero failures: Kingmaker routes 95 portrait and 15 voice mods, WotR 120 and 10. UMM code mods and asset-bundle replacements stay excluded. Hooks are unit-tested for every shape. --- .../games/game-pathfinderkingmaker/game.yaml | 47 +++---- .../src/hooks.test.ts | 107 +++++++++++++++ .../game-pathfinderkingmaker/src/hooks.ts | 122 +++++++++++++++++ .../game-pathfinderkingmaker/tsconfig.json | 9 ++ .../game.yaml | 47 +++---- .../src/hooks.test.ts | 121 +++++++++++++++++ .../src/hooks.ts | 123 ++++++++++++++++++ .../tsconfig.json | 9 ++ 8 files changed, 533 insertions(+), 52 deletions(-) create mode 100644 extensions/games/game-pathfinderkingmaker/src/hooks.test.ts create mode 100644 extensions/games/game-pathfinderkingmaker/src/hooks.ts create mode 100644 extensions/games/game-pathfinderkingmaker/tsconfig.json create mode 100644 extensions/games/game-pathfinderwrathoftherighteous/src/hooks.test.ts create mode 100644 extensions/games/game-pathfinderwrathoftherighteous/src/hooks.ts create mode 100644 extensions/games/game-pathfinderwrathoftherighteous/tsconfig.json diff --git a/extensions/games/game-pathfinderkingmaker/game.yaml b/extensions/games/game-pathfinderkingmaker/game.yaml index 0076930808..0b8424a034 100644 --- a/extensions/games/game-pathfinderkingmaker/game.yaml +++ b/extensions/games/game-pathfinderkingmaker/game.yaml @@ -19,32 +19,20 @@ context: # Custom character portraits live in the user's LocalLow profile, not the game # install. Each portrait is a folder of Small/Medium/Fulllength PNGs. portraitsRoot: ${appDataLocalLow}/Owlcat Games/Pathfinder Kingmaker/Portraits + # Wwise voice soundbanks overwrite the game's stock banks in its audio folder. + audioRoot: ${installPath}/Kingmaker_Data/StreamingAssets/Audio/Windows modTypes: - { id: portrait, name: Portrait, path: "${portraitsRoot}" } + - { id: voice, name: Voice soundbank, path: "${audioRoot}" } # A portrait folder is identified by the Small + Medium + Fulllength PNG trio. # UMM code mods (.dll) and in-game asset-bundle replacements are excluded so they # keep deploying to Mods/ and the game data folder respectively. installers: - # Multi-portrait packs wrapped in a top-level Portraits/ folder: strip the - # wrapper so each portrait subfolder lands directly under the Portraits root. - - id: portrait-collection - priority: 24 - when: - all: - - { hasFile: "**/Portraits/*/Fulllength.png" } - - { hasFile: "**/Portraits/*/Medium.png" } - - { hasFile: "**/Portraits/*/Small.png" } - unless: - any: - - { hasFile: "**/*.dll" } - - { hasFile: "**/*_Data/StreamingAssets/**" } - copy: { stripCommonRoot: true } - modType: portrait - - # A single portrait in its own folder: take that folder and place it under the - # Portraits root. + # Portraits: any archive carrying the Small/Medium/Fulllength PNG trio. A hook + # deploys each portrait folder as Portraits//, covering single-folder, + # multi-portrait Portraits/ wrappers, and loose-at-root archives. - id: portrait priority: 25 when: @@ -56,14 +44,21 @@ installers: any: - { hasFile: "**/*.dll" } - { hasFile: "**/*_Data/StreamingAssets/**" } - # Root-loose portraits have no folder name to deploy into; out of scope. - - { hasFile: "Fulllength.png" } - # Wrapped packs are handled by portrait-collection above. - - { hasFile: "**/Portraits/*/Fulllength.png" } - anchor: "**/Fulllength.png" - take: parent - placeAt: ${portraitsRoot} - modType: portrait + install: { hook: installPortrait } + + # Voice soundbanks (.bnk): a hook flattens each bank into the audio folder. + # Code mods (.dll) and data/loader mods (.json/.jbp/.patch) are excluded so + # they keep deploying to Mods/, as are multi-variant packs (handled in the hook). + - id: voice + priority: 30 + when: { hasFile: "**/*.bnk" } + unless: + any: + - { hasFile: "**/*.dll" } + - { hasFile: "**/*.json" } + - { hasFile: "**/*.jbp" } + - { hasFile: "**/*.patch" } + install: { hook: installVoice } setup: ensureDirs: diff --git a/extensions/games/game-pathfinderkingmaker/src/hooks.test.ts b/extensions/games/game-pathfinderkingmaker/src/hooks.test.ts new file mode 100644 index 0000000000..e437ec2aec --- /dev/null +++ b/extensions/games/game-pathfinderkingmaker/src/hooks.test.ts @@ -0,0 +1,107 @@ +import { describe, it, expect } from "vitest"; + +import { installPortrait, installVoice } from "./hooks"; + +type Inst = { type: string; source?: string; destination?: string; value?: unknown }; +const copies = (result: { instructions: Inst[] }): Inst[] => + result.instructions.filter((i) => i.type === "copy"); +const modType = (result: { instructions: Inst[] }): unknown => + result.instructions.find((i) => i.type === "setmodtype")?.value; + +describe("installPortrait", () => { + it("deploys a single named portrait folder under the portrait mod type", async () => { + const result = await installPortrait( + ["9999/Fulllength.png", "9999/Medium.png", "9999/Small.png", "9999/Thumbs.db"], + "/staging/x.installing", + ); + expect(modType(result)).toBe("portrait"); + expect(copies(result)).toEqual([ + { type: "copy", source: "9999/Fulllength.png", destination: "9999/Fulllength.png" }, + { type: "copy", source: "9999/Medium.png", destination: "9999/Medium.png" }, + { type: "copy", source: "9999/Small.png", destination: "9999/Small.png" }, + ]); + }); + + it("keeps every portrait in a multi-portrait Portraits/ wrapper, stripping the wrapper", async () => { + const result = await installPortrait( + [ + "Portraits/001Mercy/Fulllength.png", + "Portraits/001Mercy/Medium.png", + "Portraits/001Mercy/Small.png", + "Portraits/002Mercy/Fulllength.png", + "Portraits/002Mercy/Medium.png", + "Portraits/002Mercy/Small.png", + ], + "/staging/x", + ); + const dests = copies(result) + .map((c) => c.destination) + .sort(); + expect(dests).toEqual([ + "001Mercy/Fulllength.png", + "001Mercy/Medium.png", + "001Mercy/Small.png", + "002Mercy/Fulllength.png", + "002Mercy/Medium.png", + "002Mercy/Small.png", + ]); + }); + + it("synthesises a folder name for a loose-at-root portrait and drops non-images", async () => { + const result = await installPortrait( + ["Fulllength.png", "Medium.png", "Small.png", "Readme.txt"], + "/staging/Concept_Art_Linzi.installing", + ); + expect(copies(result)).toEqual([ + { type: "copy", source: "Fulllength.png", destination: "Concept_Art_Linzi/Fulllength.png" }, + { type: "copy", source: "Medium.png", destination: "Concept_Art_Linzi/Medium.png" }, + { type: "copy", source: "Small.png", destination: "Concept_Art_Linzi/Small.png" }, + ]); + }); + + it("takes only the immediate portrait folder regardless of nesting depth", async () => { + const result = await installPortrait( + ["Mod/sub/Name/Fulllength.png", "Mod/sub/Name/Medium.png", "Mod/sub/Name/Small.png"], + "/staging/x", + ); + expect(copies(result).map((c) => c.destination)).toEqual([ + "Name/Fulllength.png", + "Name/Medium.png", + "Name/Small.png", + ]); + }); +}); + +describe("installVoice", () => { + it("flattens a single .bnk into the audio folder and tags the voice mod type", async () => { + const result = await installVoice( + ["Vax (Madman)/PC_Male_Madman_GVR_ENG.bnk", "Readme.txt"], + "/staging/x.installing", + ); + expect(modType(result)).toBe("voice"); + expect(copies(result)).toEqual([ + { + type: "copy", + source: "Vax (Madman)/PC_Male_Madman_GVR_ENG.bnk", + destination: "PC_Male_Madman_GVR_ENG.bnk", + }, + ]); + }); + + it("flattens several distinct banks regardless of nesting", async () => { + const result = await installVoice(["Voices/Angelina/A.bnk", "Voices/Chen/B.bnk"], "/staging/x"); + expect(copies(result).map((c) => c.destination)).toEqual(["A.bnk", "B.bnk"]); + }); + + it("defers a multi-variant pack to the Mods folder with no voice mod type", async () => { + const result = await installVoice( + ["magic goblin/PC_Male_Madman_GVR_ENG.bnk", "stabby goblin/PC_Male_Madman_GVR_ENG.bnk"], + "/staging/x", + ); + expect(modType(result)).toBeUndefined(); + expect(copies(result).map((c) => c.destination)).toEqual([ + "magic goblin/PC_Male_Madman_GVR_ENG.bnk", + "stabby goblin/PC_Male_Madman_GVR_ENG.bnk", + ]); + }); +}); diff --git a/extensions/games/game-pathfinderkingmaker/src/hooks.ts b/extensions/games/game-pathfinderkingmaker/src/hooks.ts new file mode 100644 index 0000000000..48f140bebc --- /dev/null +++ b/extensions/games/game-pathfinderkingmaker/src/hooks.ts @@ -0,0 +1,122 @@ +/** + * Imperative install hooks for the Pathfinder: Kingmaker GDL extension. + * + * Two mod shapes need logic GDL cannot express declaratively, and both deploy + * outside the game's Mods folder (portraits to the user's LocalLow profile, + * voice banks to the game's audio folder). Doing the placement in a hook also + * keeps the install free of context-binding interpolation, which only resolves + * once Vortex has run the game's setup. + * + * - installPortrait: a portrait is a folder holding the Small/Medium/Fulllength + * PNG trio. Archives ship them as a single named folder, several folders + * under a Portraits/ wrapper, or loose at the archive root with no folder. + * The hook finds every trio folder and deploys each as Portraits//, + * synthesising a name from the mod for the loose-at-root case. + * - installVoice: Wwise .bnk soundbanks that overwrite the game's banks. The + * hook flattens every .bnk into the audio folder. Packs that bundle several + * variants of the same bank are a "pick one" choice an installer cannot + * make, so those deploy to the Mods folder unchanged for the user to resolve. + * + * These hooks are game-agnostic; the Wrath of the Righteous extension uses an + * identical copy. The per-game audio and portrait paths live in game.yaml. + */ +import { types } from "@nexusmods/vortex-api"; + +const PORTRAIT_MOD_TYPE = "portrait"; +const VOICE_MOD_TYPE = "voice"; + +const isDir = (file: string): boolean => file.endsWith("/") || file.endsWith("\\"); +const baseName = (file: string): string => file.split(/[\\/]/).pop() ?? file; +const dirName = (file: string): string => { + const norm = file.replace(/\\/g, "/"); + const slash = norm.lastIndexOf("/"); + return slash < 0 ? "" : norm.slice(0, slash); +}; +const isImage = (file: string): boolean => /\.(png|jpe?g|webp)$/i.test(file); + +/** Turn a staging-folder path into a stable, unique portrait subfolder name. */ +function portraitFolderName(destinationPath: string): string { + const name = baseName(destinationPath) + .replace(/\.installing$/i, "") + .trim(); + return name.length > 0 ? name : "Portrait"; +} + +/** + * Deploy every portrait folder (a directory holding the Small/Medium/Fulllength + * trio) as Portraits//. Handles single-folder, multi-portrait wrapper, + * and loose-at-root archives at any nesting depth. Non-image files are dropped. + */ +export async function installPortrait( + files: string[], + destinationPath: string, +): Promise { + const byDir = new Map(); + for (const file of files) { + if (isDir(file)) continue; + const dir = dirName(file); + const list = byDir.get(dir) ?? []; + list.push(file); + byDir.set(dir, list); + } + + const hasTrio = (dirFiles: string[]): boolean => { + const names = new Set(dirFiles.map((f) => baseName(f).toLowerCase())); + return names.has("fulllength.png") && names.has("medium.png") && names.has("small.png"); + }; + + const copies: types.IInstruction[] = []; + for (const [dir, dirFiles] of byDir) { + if (!hasTrio(dirFiles)) continue; + const folder = dir === "" ? portraitFolderName(destinationPath) : baseName(dir); + for (const file of dirFiles) { + if (isImage(file)) { + copies.push({ + type: "copy" as const, + source: file, + destination: `${folder}/${baseName(file)}`, + }); + } + } + } + + return { + instructions: [{ type: "setmodtype" as const, value: PORTRAIT_MOD_TYPE }, ...copies], + }; +} + +/** + * Voice soundbank: flatten every .bnk into the audio folder. If the archive + * bundles multiple variants of the same bank (the same .bnk filename under more + * than one folder), defer to the Mods folder by preserving the archive layout + * and leaving the mod type at its default, so the user can pick a variant. + */ +export async function installVoice( + files: string[], + _destinationPath: string, +): Promise { + const bnks = files.filter((file) => !isDir(file) && /\.bnk$/i.test(file)); + + const counts = new Map(); + for (const bnk of bnks) { + const key = baseName(bnk).toLowerCase(); + counts.set(key, (counts.get(key) ?? 0) + 1); + } + const multiVariant = [...counts.values()].some((count) => count > 1); + + if (multiVariant) { + const copies: types.IInstruction[] = files + .filter((file) => !isDir(file)) + .map((file) => ({ type: "copy" as const, source: file, destination: file })); + return { instructions: copies }; + } + + const copies: types.IInstruction[] = bnks.map((bnk) => ({ + type: "copy" as const, + source: bnk, + destination: baseName(bnk), + })); + return { + instructions: [{ type: "setmodtype" as const, value: VOICE_MOD_TYPE }, ...copies], + }; +} diff --git a/extensions/games/game-pathfinderkingmaker/tsconfig.json b/extensions/games/game-pathfinderkingmaker/tsconfig.json new file mode 100644 index 0000000000..fe6263edbb --- /dev/null +++ b/extensions/games/game-pathfinderkingmaker/tsconfig.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://www.schemastore.org/tsconfig.json", + "extends": "../../tsconfig.extensions.json", + "compilerOptions": { + "strictNullChecks": true, + "noUncheckedIndexedAccess": true + }, + "include": ["src"] +} diff --git a/extensions/games/game-pathfinderwrathoftherighteous/game.yaml b/extensions/games/game-pathfinderwrathoftherighteous/game.yaml index f662771d0a..9cb04dcebd 100644 --- a/extensions/games/game-pathfinderwrathoftherighteous/game.yaml +++ b/extensions/games/game-pathfinderwrathoftherighteous/game.yaml @@ -20,9 +20,12 @@ context: # Custom character portraits live in the user's LocalLow profile, not the game # install. Each portrait is a folder of Small/Medium/Fulllength PNGs. portraitsRoot: ${appDataLocalLow}/Owlcat Games/Pathfinder Wrath Of The Righteous/Portraits + # Wwise voice soundbanks overwrite the game's stock banks in its audio folder. + audioRoot: ${installPath}/Wrath_Data/StreamingAssets/Audio/Windows modTypes: - { id: portrait, name: Portrait, path: "${portraitsRoot}" } + - { id: voice, name: Voice soundbank, path: "${audioRoot}" } # Reads the build version from Version.info. The original extension split the # file on spaces and took the 4th token; the regex captures that same token. @@ -35,24 +38,9 @@ discovery: # UMM code mods (.dll) and in-game asset-bundle replacements are excluded so they # keep deploying to Mods/ and the game data folder respectively. installers: - # Multi-portrait packs wrapped in a top-level Portraits/ folder: strip the - # wrapper so each portrait subfolder lands directly under the Portraits root. - - id: portrait-collection - priority: 24 - when: - all: - - { hasFile: "**/Portraits/*/Fulllength.png" } - - { hasFile: "**/Portraits/*/Medium.png" } - - { hasFile: "**/Portraits/*/Small.png" } - unless: - any: - - { hasFile: "**/*.dll" } - - { hasFile: "**/*_Data/StreamingAssets/**" } - copy: { stripCommonRoot: true } - modType: portrait - - # A single portrait in its own folder: take that folder and place it under the - # Portraits root. + # Portraits: any archive carrying the Small/Medium/Fulllength PNG trio. A hook + # deploys each portrait folder as Portraits//, covering single-folder, + # multi-portrait Portraits/ wrappers, and loose-at-root archives. - id: portrait priority: 25 when: @@ -64,14 +52,21 @@ installers: any: - { hasFile: "**/*.dll" } - { hasFile: "**/*_Data/StreamingAssets/**" } - # Root-loose portraits have no folder name to deploy into; out of scope. - - { hasFile: "Fulllength.png" } - # Wrapped packs are handled by portrait-collection above. - - { hasFile: "**/Portraits/*/Fulllength.png" } - anchor: "**/Fulllength.png" - take: parent - placeAt: ${portraitsRoot} - modType: portrait + install: { hook: installPortrait } + + # Voice soundbanks (.bnk): a hook flattens each bank into the audio folder. + # Code mods (.dll) and data/loader mods (.json/.jbp/.patch) are excluded so + # they keep deploying to Mods/, as are multi-variant packs (handled in the hook). + - id: voice + priority: 30 + when: { hasFile: "**/*.bnk" } + unless: + any: + - { hasFile: "**/*.dll" } + - { hasFile: "**/*.json" } + - { hasFile: "**/*.jbp" } + - { hasFile: "**/*.patch" } + install: { hook: installVoice } setup: ensureDirs: diff --git a/extensions/games/game-pathfinderwrathoftherighteous/src/hooks.test.ts b/extensions/games/game-pathfinderwrathoftherighteous/src/hooks.test.ts new file mode 100644 index 0000000000..c3d850daac --- /dev/null +++ b/extensions/games/game-pathfinderwrathoftherighteous/src/hooks.test.ts @@ -0,0 +1,121 @@ +import { describe, it, expect } from "vitest"; + +import { installPortrait, installVoice } from "./hooks"; + +type Inst = { type: string; source?: string; destination?: string; value?: unknown }; +const copies = (result: { instructions: Inst[] }): Inst[] => + result.instructions.filter((i) => i.type === "copy"); +const modType = (result: { instructions: Inst[] }): unknown => + result.instructions.find((i) => i.type === "setmodtype")?.value; + +describe("installPortrait", () => { + it("deploys a single named portrait folder under the portrait mod type", async () => { + const result = await installPortrait( + [ + "Camellia/Fulllength.png", + "Camellia/Medium.png", + "Camellia/Small.png", + "Camellia/Thumbs.db", + ], + "/staging/x.installing", + ); + expect(modType(result)).toBe("portrait"); + expect(copies(result)).toEqual([ + { type: "copy", source: "Camellia/Fulllength.png", destination: "Camellia/Fulllength.png" }, + { type: "copy", source: "Camellia/Medium.png", destination: "Camellia/Medium.png" }, + { type: "copy", source: "Camellia/Small.png", destination: "Camellia/Small.png" }, + ]); + }); + + it("keeps every portrait in a multi-portrait Portraits/ wrapper, stripping the wrapper", async () => { + const result = await installPortrait( + [ + "Portraits/Angel/Fulllength.png", + "Portraits/Angel/Medium.png", + "Portraits/Angel/Small.png", + "Portraits/Demon/Fulllength.png", + "Portraits/Demon/Medium.png", + "Portraits/Demon/Small.png", + ], + "/staging/x", + ); + const dests = copies(result) + .map((c) => c.destination) + .sort(); + expect(dests).toEqual([ + "Angel/Fulllength.png", + "Angel/Medium.png", + "Angel/Small.png", + "Demon/Fulllength.png", + "Demon/Medium.png", + "Demon/Small.png", + ]); + }); + + it("synthesises a folder name for a loose-at-root portrait and drops non-images", async () => { + const result = await installPortrait( + ["Fulllength.png", "Medium.png", "Small.png", "Readme.txt"], + "/staging/Camellia_Remastered.installing", + ); + expect(copies(result)).toEqual([ + { type: "copy", source: "Fulllength.png", destination: "Camellia_Remastered/Fulllength.png" }, + { type: "copy", source: "Medium.png", destination: "Camellia_Remastered/Medium.png" }, + { type: "copy", source: "Small.png", destination: "Camellia_Remastered/Small.png" }, + ]); + }); + + it("takes only the immediate portrait folder regardless of nesting depth", async () => { + const result = await installPortrait( + ["Mod/sub/Name/Fulllength.png", "Mod/sub/Name/Medium.png", "Mod/sub/Name/Small.png"], + "/staging/x", + ); + expect(copies(result).map((c) => c.destination)).toEqual([ + "Name/Fulllength.png", + "Name/Medium.png", + "Name/Small.png", + ]); + }); +}); + +describe("installVoice", () => { + it("flattens a single .bnk into the audio folder and tags the voice mod type", async () => { + const result = await installVoice( + ["Alistair Voice Pack/PC_Male_Optimist_GVR_ENG.bnk", "Readme.txt"], + "/staging/x.installing", + ); + expect(modType(result)).toBe("voice"); + expect(copies(result)).toEqual([ + { + type: "copy", + source: "Alistair Voice Pack/PC_Male_Optimist_GVR_ENG.bnk", + destination: "PC_Male_Optimist_GVR_ENG.bnk", + }, + ]); + }); + + it("flattens several distinct banks regardless of nesting", async () => { + const result = await installVoice( + [ + "WOTR Voices/Angelina/PC_Female_Carefree_GVR_ENG.bnk", + "WOTR Voices/Chen/PC_Male_Brave_GVR_ENG.bnk", + ], + "/staging/x", + ); + expect(copies(result).map((c) => c.destination)).toEqual([ + "PC_Female_Carefree_GVR_ENG.bnk", + "PC_Male_Brave_GVR_ENG.bnk", + ]); + }); + + it("defers a multi-variant pack to the Mods folder with no voice mod type", async () => { + const result = await installVoice( + ["variant a/PC_Male_Madman_GVR_ENG.bnk", "variant b/PC_Male_Madman_GVR_ENG.bnk"], + "/staging/x", + ); + expect(modType(result)).toBeUndefined(); + expect(copies(result).map((c) => c.destination)).toEqual([ + "variant a/PC_Male_Madman_GVR_ENG.bnk", + "variant b/PC_Male_Madman_GVR_ENG.bnk", + ]); + }); +}); diff --git a/extensions/games/game-pathfinderwrathoftherighteous/src/hooks.ts b/extensions/games/game-pathfinderwrathoftherighteous/src/hooks.ts new file mode 100644 index 0000000000..9573be2f5b --- /dev/null +++ b/extensions/games/game-pathfinderwrathoftherighteous/src/hooks.ts @@ -0,0 +1,123 @@ +/** + * Imperative install hooks for the Pathfinder: Wrath of the Righteous GDL + * extension. + * + * Two mod shapes need logic GDL cannot express declaratively, and both deploy + * outside the game's Mods folder (portraits to the user's LocalLow profile, + * voice banks to the game's audio folder). Doing the placement in a hook also + * keeps the install free of context-binding interpolation, which only resolves + * once Vortex has run the game's setup. + * + * - installPortrait: a portrait is a folder holding the Small/Medium/Fulllength + * PNG trio. Archives ship them as a single named folder, several folders + * under a Portraits/ wrapper, or loose at the archive root with no folder. + * The hook finds every trio folder and deploys each as Portraits//, + * synthesising a name from the mod for the loose-at-root case. + * - installVoice: Wwise .bnk soundbanks that overwrite the game's banks. The + * hook flattens every .bnk into the audio folder. Packs that bundle several + * variants of the same bank are a "pick one" choice an installer cannot + * make, so those deploy to the Mods folder unchanged for the user to resolve. + * + * These hooks are game-agnostic; the Kingmaker extension uses an identical copy. + * The per-game audio and portrait paths live in game.yaml. + */ +import { types } from "@nexusmods/vortex-api"; + +const PORTRAIT_MOD_TYPE = "portrait"; +const VOICE_MOD_TYPE = "voice"; + +const isDir = (file: string): boolean => file.endsWith("/") || file.endsWith("\\"); +const baseName = (file: string): string => file.split(/[\\/]/).pop() ?? file; +const dirName = (file: string): string => { + const norm = file.replace(/\\/g, "/"); + const slash = norm.lastIndexOf("/"); + return slash < 0 ? "" : norm.slice(0, slash); +}; +const isImage = (file: string): boolean => /\.(png|jpe?g|webp)$/i.test(file); + +/** Turn a staging-folder path into a stable, unique portrait subfolder name. */ +function portraitFolderName(destinationPath: string): string { + const name = baseName(destinationPath) + .replace(/\.installing$/i, "") + .trim(); + return name.length > 0 ? name : "Portrait"; +} + +/** + * Deploy every portrait folder (a directory holding the Small/Medium/Fulllength + * trio) as Portraits//. Handles single-folder, multi-portrait wrapper, + * and loose-at-root archives at any nesting depth. Non-image files are dropped. + */ +export async function installPortrait( + files: string[], + destinationPath: string, +): Promise { + const byDir = new Map(); + for (const file of files) { + if (isDir(file)) continue; + const dir = dirName(file); + const list = byDir.get(dir) ?? []; + list.push(file); + byDir.set(dir, list); + } + + const hasTrio = (dirFiles: string[]): boolean => { + const names = new Set(dirFiles.map((f) => baseName(f).toLowerCase())); + return names.has("fulllength.png") && names.has("medium.png") && names.has("small.png"); + }; + + const copies: types.IInstruction[] = []; + for (const [dir, dirFiles] of byDir) { + if (!hasTrio(dirFiles)) continue; + const folder = dir === "" ? portraitFolderName(destinationPath) : baseName(dir); + for (const file of dirFiles) { + if (isImage(file)) { + copies.push({ + type: "copy" as const, + source: file, + destination: `${folder}/${baseName(file)}`, + }); + } + } + } + + return { + instructions: [{ type: "setmodtype" as const, value: PORTRAIT_MOD_TYPE }, ...copies], + }; +} + +/** + * Voice soundbank: flatten every .bnk into the audio folder. If the archive + * bundles multiple variants of the same bank (the same .bnk filename under more + * than one folder), defer to the Mods folder by preserving the archive layout + * and leaving the mod type at its default, so the user can pick a variant. + */ +export async function installVoice( + files: string[], + _destinationPath: string, +): Promise { + const bnks = files.filter((file) => !isDir(file) && /\.bnk$/i.test(file)); + + const counts = new Map(); + for (const bnk of bnks) { + const key = baseName(bnk).toLowerCase(); + counts.set(key, (counts.get(key) ?? 0) + 1); + } + const multiVariant = [...counts.values()].some((count) => count > 1); + + if (multiVariant) { + const copies: types.IInstruction[] = files + .filter((file) => !isDir(file)) + .map((file) => ({ type: "copy" as const, source: file, destination: file })); + return { instructions: copies }; + } + + const copies: types.IInstruction[] = bnks.map((bnk) => ({ + type: "copy" as const, + source: bnk, + destination: baseName(bnk), + })); + return { + instructions: [{ type: "setmodtype" as const, value: VOICE_MOD_TYPE }, ...copies], + }; +} diff --git a/extensions/games/game-pathfinderwrathoftherighteous/tsconfig.json b/extensions/games/game-pathfinderwrathoftherighteous/tsconfig.json new file mode 100644 index 0000000000..fe6263edbb --- /dev/null +++ b/extensions/games/game-pathfinderwrathoftherighteous/tsconfig.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://www.schemastore.org/tsconfig.json", + "extends": "../../tsconfig.extensions.json", + "compilerOptions": { + "strictNullChecks": true, + "noUncheckedIndexedAccess": true + }, + "include": ["src"] +} From f0c6cf99a4c90b2f418931674dcd8190158c6936 Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Mon, 22 Jun 2026 07:24:42 -0700 Subject: [PATCH 8/9] chore: drop superpowers plan/spec docs and ignore the dir --- .gitignore | 1 + .../2026-06-17-pathfinder-gdl-conversion.md | 1339 ----------------- ...-06-17-pathfinder-gdl-conversion-design.md | 245 --- 3 files changed, 1 insertion(+), 1584 deletions(-) delete mode 100644 docs/superpowers/plans/2026-06-17-pathfinder-gdl-conversion.md delete mode 100644 docs/superpowers/specs/2026-06-17-pathfinder-gdl-conversion-design.md diff --git a/.gitignore b/.gitignore index 99a7559b38..8eb7c6d5dd 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ dist_portable dist_web .gdl-out **/tests/cache +docs/superpowers/ out doc coverage diff --git a/docs/superpowers/plans/2026-06-17-pathfinder-gdl-conversion.md b/docs/superpowers/plans/2026-06-17-pathfinder-gdl-conversion.md deleted file mode 100644 index 3d59f87dd5..0000000000 --- a/docs/superpowers/plans/2026-06-17-pathfinder-gdl-conversion.md +++ /dev/null @@ -1,1339 +0,0 @@ -# Pathfinder to GDL Conversion Implementation Plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Convert the two Owlcat Pathfinder game extensions (Kingmaker, Wrath of the Righteous) to run off the Game Description Language (GDL), adding one new declarative GDL feature (`setup.requireFiles`) to cover the Unity Mod Manager prompt. - -**Architecture:** Two phases. Phase A adds a `setup.requireFiles` block to the `game-description-language` submodule (parser, validator, codegen, runtime, type stub, tests). Phase B rewrites each Pathfinder extension as a single declarative `game.yaml`, deletes the old imperative source, and bumps the submodule pointer in Vortex. - -**Tech Stack:** TypeScript, GDL toolchain (YAML to webpack-bundled Vortex extension), vitest, pnpm workspaces, git submodule. - ---- - -## Design reference - -Full design: `docs/superpowers/specs/2026-06-17-pathfinder-gdl-conversion-design.md`. - -Settled decisions baked into this plan: - -- Both games drop `modtype-umm` integration (`requireExtension`, `ummAddGame`). They become self-contained. WotR loses UMM auto-download and `umm` mod-type activation (accepted regression). -- The UMM presence check is purely path based (no registry). -- The prompt button opens a Nexus mod page (`domain` + `modId`) or a plain `url`. No silent install. -- The `requireFiles` step is informational; it does not reject `setup` (the original Kingmaker `UserCanceled` quirk is dropped). - -## Deviations from the spec to confirm with the user - -- **No webp conversion.** No webp encoder is installed (`cwebp`/ImageMagick/sharp absent). The plan keeps `gameart.jpg` and references it directly. webp is optional polish, not a functional requirement. The GDL build copies whatever logo filename `game.yaml` names. -- **No `tests: { corpus: nexus }` in the game.yaml.** Both games register zero installers (mods deploy to `Mods/` via Vortex's default), so corpus installer-routing tests have nothing to assert. The `requireFiles` feature is fully unit-tested in the GDL repo instead. Game-side verification is the GDL build succeeding plus produced `dist/` artifacts. - -## File structure - -**Phase A — `game-description-language` submodule (separate repo, branch off `main`):** - -- Modify: `src/parser/ast.ts` — add `requireFiles?` to `SetupNode` and new node interfaces. -- Modify: `src/parser/index.ts` — parse `setup.requireFiles` (new `parseRequireFiles` helper). -- Modify: `src/schema/validator.ts` — field rules for `requireFiles`. -- Modify: `src/types/vortex-api.d.ts` — declare `fs.statAsync` and `api.showDialog`. -- Modify: `src/runtime/vortex-shim.ts` — `RequireFilesSpec` type, trailing `registerGame` param, setup logic, `runRequireFilesCheck` method. -- Modify: `src/codegen/emit.ts` — emit the `requireFiles` literal (build URL from `mod`). -- Test: `tests/require-files.test.ts` — parser, validator, runtime, codegen cases for the feature. - -**Phase B — Vortex repo (branch `halgari/pathfinder-to-gdl`, already created):** - -- For each of `extensions/games/game-pathfinderkingmaker/` and `extensions/games/game-pathfinderwrathoftherighteous/`: - - Create: `game.yaml`, `build.mjs`, `vitest.config.ts`, `gameart.jpg` (moved from `assets/`). - - Rewrite: `package.json`. - - Delete: `src/index.js` / `src/index.ts`, `assets/` (including unused `umm.png`), `tsconfig.tsbuildinfo`, any old build script. -- Modify: the submodule pointer (Vortex records the new `game-description-language` commit). - ---- - -# Phase A: GDL `setup.requireFiles` feature - -All Phase A work happens inside the submodule directory `game-description-language/`. Commands below assume you are `cd`'d into that directory unless stated otherwise. - -### Task A0: Create the feature branch in the submodule - -- [ ] **Step 1: Branch off main** - -Run (from repo root `/c/oss/Vortex`): - -```bash -git -C game-description-language fetch origin -git -C game-description-language checkout -B feat/setup-require-files origin/main -``` - -- [ ] **Step 2: Confirm clean baseline build and tests** - -Run: - -```bash -cd game-description-language && pnpm install --frozen-lockfile && pnpm build && pnpm test -``` - -Expected: build succeeds, full suite passes (the baseline ~154 tests green). - ---- - -### Task A1: AST types for `requireFiles` - -**Files:** - -- Modify: `game-description-language/src/parser/ast.ts:247-251` (the `SetupNode` interface) - -- [ ] **Step 1: Extend `SetupNode` and add node types** - -Replace the existing `SetupNode` interface (currently): - -```ts -export interface SetupNode extends Node { - kind: "setup"; - ensureDirs: string[]; // path templates, interpolated against context -} -``` - -with: - -```ts -export interface SetupNode extends Node { - kind: "setup"; - ensureDirs: string[]; // path templates, interpolated against context - requireFiles?: RequireFilesNode; -} - -// Declarative prerequisite check: stat a list of files at setup time and, when -// any are missing, show an informational dialog that points the user at a mod -// page or URL to download the missing prerequisite (e.g. Unity Mod Manager). -export interface RequireFilesNode { - files: string[]; // path templates, interpolated against context - prompt: RequireFilesPrompt; -} - -export interface RequireFilesPrompt { - title: string; - message: string; - link?: RequireFilesLink; -} - -export interface RequireFilesLink { - label: string; // button text - target: RequireFilesTarget; -} - -export type RequireFilesTarget = - | { kind: "mod"; domain: string; modId: number } - | { kind: "url"; url: string }; -``` - -- [ ] **Step 2: Typecheck** - -Run: `cd game-description-language && pnpm exec tsc --noEmit` -Expected: PASS (no references yet, types compile). - -- [ ] **Step 3: Commit** - -```bash -git -C game-description-language add src/parser/ast.ts -git -C game-description-language commit -m "feat(ast): add requireFiles to SetupNode" -``` - ---- - -### Task A2: Parse `setup.requireFiles` - -**Files:** - -- Modify: `game-description-language/src/parser/index.ts` (the `setup` block near line 884, plus a new helper) -- Test: `game-description-language/tests/require-files.test.ts` - -- [ ] **Step 1: Write the failing parser test** - -Create `game-description-language/tests/require-files.test.ts`: - -```ts -import { describe, it, expect } from "vitest"; -import { parseYaml } from "../src/parser/index.js"; - -const YAML = `gdl: 1 -game: - id: g - name: G - executable: G.exe - requiredFiles: [G.exe] -stores: - steam: "1" -setup: - ensureDirs: - - \${installPath}/Mods - requireFiles: - files: - - \${installPath}/UnityModManager/UnityModManager.dll - prompt: - title: Action required - message: Install UMM - link: - label: Get UMM - mod: { domain: site, modId: 21 } -`; - -describe("parser: setup.requireFiles", () => { - it("parses files, prompt, and a mod link target", () => { - const doc = parseYaml(YAML, "rf.yaml"); - const rf = doc.setup?.requireFiles; - expect(rf?.files).toEqual(["${installPath}/UnityModManager/UnityModManager.dll"]); - expect(rf?.prompt.title).toBe("Action required"); - expect(rf?.prompt.message).toBe("Install UMM"); - expect(rf?.prompt.link?.label).toBe("Get UMM"); - expect(rf?.prompt.link?.target).toEqual({ kind: "mod", domain: "site", modId: 21 }); - }); - - it("parses a url link target", () => { - const doc = parseYaml( - YAML.replace("mod: { domain: site, modId: 21 }", "url: https://example.com/umm"), - "rf.yaml", - ); - expect(doc.setup?.requireFiles?.prompt.link?.target).toEqual({ - kind: "url", - url: "https://example.com/umm", - }); - }); -}); -``` - -- [ ] **Step 2: Run test to verify it fails** - -Run: `cd game-description-language && pnpm exec vitest run tests/require-files.test.ts` -Expected: FAIL (`rf` is undefined — parser ignores `requireFiles`). - -- [ ] **Step 3: Add the import and parse logic** - -In `src/parser/index.ts`, add the new AST types to the existing `ast.js` import (find the import line that already pulls `SetupNode` and add the new names): - -```ts -import type { - // ...existing imports... - SetupNode, - RequireFilesNode, - RequireFilesLink, - RequireFilesTarget, -} from "./ast.js"; -``` - -(Only add the names not already present; `SetupNode` is likely already imported.) - -Replace the existing `setup` assembly block (currently building `setup = { kind: 'setup', ensureDirs: dirs, span }`) so it also parses `requireFiles`: - -```ts -let requireFiles: RequireFilesNode | undefined; -const rfYaml = setupYaml.get("requireFiles", true); -if (isMap(rfYaml)) { - requireFiles = parseRequireFiles(rfYaml, file, source); -} -setup = { - kind: "setup", - ensureDirs: dirs, - ...(requireFiles !== undefined && { requireFiles }), - span: spanOf(file, source, setupYaml), -}; -``` - -Add this helper near the other parse helpers (e.g. just above `parseYaml` or beside `parseToolbarActionTarget`). It mirrors the structural-error style used by the `ensureDirs` parser: - -```ts -function parseRequireFiles(node: YAMLMap, file: string, source: string): RequireFilesNode { - const files: string[] = []; - const filesYaml = node.get("files", true); - if (isSeq(filesYaml)) { - for (const item of filesYaml.items) { - if (isScalar(item) && typeof item.value === "string") { - files.push(item.value); - } else { - throw new BuildErrors([ - { - code: "GDL153", - message: "setup.requireFiles.files entries must be strings", - span: spanOf(file, source, item as YamlNode), - }, - ]); - } - } - } - - const promptYaml = node.get("prompt", true); - if (!isMap(promptYaml)) { - throw new BuildErrors([ - { - code: "GDL154", - message: "setup.requireFiles.prompt must be a mapping with title and message", - span: spanOf(file, source, node), - }, - ]); - } - const title = String(promptYaml.get("title") ?? ""); - const message = String(promptYaml.get("message") ?? ""); - - let link: RequireFilesLink | undefined; - const linkYaml = promptYaml.get("link", true); - if (isMap(linkYaml)) { - const label = String(linkYaml.get("label") ?? ""); - const modYaml = linkYaml.get("mod", true); - const urlYaml = linkYaml.get("url", true); - let target: RequireFilesTarget; - if (isMap(modYaml)) { - target = { - kind: "mod", - domain: String(modYaml.get("domain") ?? ""), - modId: Number(modYaml.get("modId") ?? 0), - }; - } else if (isScalar(urlYaml) && typeof urlYaml.value === "string") { - target = { kind: "url", url: urlYaml.value }; - } else { - throw new BuildErrors([ - { - code: "GDL156", - message: - "setup.requireFiles.prompt.link must set exactly one of `mod` or `url`", - span: spanOf(file, source, linkYaml), - }, - ]); - } - link = { label, target }; - } - - return { files, prompt: { title, message, ...(link !== undefined && { link }) } }; -} -``` - -Note: `YAMLMap` and `YamlNode` types are already imported/used elsewhere in this file (see `parseToolbarActionTarget`); reuse the same type names. If `YAMLMap` is not yet imported, use the same `yaml` import the file already relies on. - -- [ ] **Step 4: Run test to verify it passes** - -Run: `cd game-description-language && pnpm exec vitest run tests/require-files.test.ts` -Expected: PASS (both parser cases). - -- [ ] **Step 5: Typecheck and commit** - -Run: `cd game-description-language && pnpm exec tsc --noEmit` -Expected: PASS. - -```bash -git -C game-description-language add src/parser/index.ts tests/require-files.test.ts -git -C game-description-language commit -m "feat(parser): parse setup.requireFiles" -``` - ---- - -### Task A3: Validate `requireFiles` - -**Files:** - -- Modify: `game-description-language/src/schema/validator.ts` (inside the `if (doc.setup)` block, after the `ensureDirs` checks near line 390-399) -- Test: `game-description-language/tests/require-files.test.ts` (append) - -- [ ] **Step 1: Write the failing validator tests** - -Append to `tests/require-files.test.ts`: - -```ts -import { validate } from "../src/schema/validator.js"; - -const baseYaml = (rf: string) => `gdl: 1 -game: - id: g - name: G - executable: G.exe - requiredFiles: [G.exe] -stores: - steam: "1" -setup: - ensureDirs: - - \${installPath}/Mods - requireFiles: -${rf} -`; - -describe("validator: setup.requireFiles", () => { - it("accepts a well-formed requireFiles block", () => { - const doc = parseYaml( - baseYaml( - ` files: - - \${installPath}/x.dll - prompt: - title: T - message: M - link: - label: L - mod: { domain: site, modId: 21 }`, - ), - "rf.yaml", - ); - expect(validate(doc).filter((e) => e.code.startsWith("GDL15"))).toEqual([]); - }); - - it("rejects an empty files list", () => { - const doc = parseYaml( - baseYaml( - ` files: [] - prompt: - title: T - message: M`, - ), - "rf.yaml", - ); - expect(validate(doc).some((e) => e.code === "GDL153")).toBe(true); - }); - - it("rejects a missing prompt title", () => { - const doc = parseYaml( - baseYaml( - ` files: - - \${installPath}/x.dll - prompt: - title: "" - message: M`, - ), - "rf.yaml", - ); - expect(validate(doc).some((e) => e.code === "GDL154")).toBe(true); - }); - - it("rejects a link with an empty mod domain", () => { - const doc = parseYaml( - baseYaml( - ` files: - - \${installPath}/x.dll - prompt: - title: T - message: M - link: - label: L - mod: { domain: "", modId: 21 }`, - ), - "rf.yaml", - ); - expect(validate(doc).some((e) => e.code === "GDL155")).toBe(true); - }); -}); -``` - -- [ ] **Step 2: Run to verify failure** - -Run: `cd game-description-language && pnpm exec vitest run tests/require-files.test.ts -t "validator: setup.requireFiles"` -Expected: FAIL (no GDL153/154/155 emitted yet). - -- [ ] **Step 3: Add validation** - -In `src/schema/validator.ts`, inside the existing `if (doc.setup) {` block, after the `ensureDirs` loop, add: - -```ts -const rf = doc.setup.requireFiles; -if (rf) { - if (rf.files.length === 0) { - errors.push({ - code: "GDL153", - message: "setup.requireFiles.files must not be empty", - span: doc.setup.span, - }); - } - rf.files.forEach((f, i) => { - if (f.trim() === "") { - errors.push({ - code: "GDL153", - message: `setup.requireFiles.files[${i}] must not be empty`, - span: doc.setup!.span, - }); - } - }); - if (rf.prompt.title.trim() === "") { - errors.push({ - code: "GDL154", - message: "setup.requireFiles.prompt.title must not be empty", - span: doc.setup.span, - }); - } - if (rf.prompt.message.trim() === "") { - errors.push({ - code: "GDL154", - message: "setup.requireFiles.prompt.message must not be empty", - span: doc.setup.span, - }); - } - if (rf.prompt.link) { - const link = rf.prompt.link; - if (link.label.trim() === "") { - errors.push({ - code: "GDL155", - message: "setup.requireFiles.prompt.link.label must not be empty", - span: doc.setup.span, - }); - } - if ( - link.target.kind === "mod" && - (link.target.domain.trim() === "" || - !Number.isFinite(link.target.modId) || - link.target.modId <= 0) - ) { - errors.push({ - code: "GDL155", - message: "setup.requireFiles.prompt.link.mod needs a domain and a positive modId", - span: doc.setup.span, - }); - } - if (link.target.kind === "url" && link.target.url.trim() === "") { - errors.push({ - code: "GDL155", - message: "setup.requireFiles.prompt.link.url must not be empty", - span: doc.setup.span, - }); - } - } -} -``` - -- [ ] **Step 4: Run to verify pass** - -Run: `cd game-description-language && pnpm exec vitest run tests/require-files.test.ts` -Expected: PASS (all parser + validator cases). - -- [ ] **Step 5: Typecheck and commit** - -Run: `cd game-description-language && pnpm exec tsc --noEmit` - -```bash -git -C game-description-language add src/schema/validator.ts tests/require-files.test.ts -git -C game-description-language commit -m "feat(validator): enforce setup.requireFiles field rules" -``` - ---- - -### Task A4: Extend the `vortex-api` type stub - -**Files:** - -- Modify: `game-description-language/src/types/vortex-api.d.ts:116-118` (`fs`) and `:93-98` (`api`) - -The runtime shim (Task A5) calls `fs.statAsync` and `api.showDialog`, neither of which the stub declares. Add them first so A5 typechecks. - -- [ ] **Step 1: Add `fs.statAsync`** - -Replace: - -```ts -export const fs: { - ensureDirWritableAsync: (path: string) => Promise; -}; -``` - -with: - -```ts -export const fs: { - ensureDirWritableAsync: (path: string) => Promise; - statAsync: (path: string) => Promise<{ isDirectory: () => boolean }>; -}; -``` - -- [ ] **Step 2: Add `showDialog` to the context `api` type** - -Replace the `api: { ... }` block inside `IExtensionContext` (currently `getState` + `events.on`) with: - -```ts - api: { - getState: () => unknown; - events: { - on: (event: string, handler: (...args: unknown[]) => void) => void; - }; - showDialog: ( - type: string, - title: string, - content: { text?: string; message?: string; bbcode?: string }, - actions: Array<{ label: string; action?: () => void }>, - ) => Promise; - }; -``` - -- [ ] **Step 3: Typecheck and commit** - -Run: `cd game-description-language && pnpm exec tsc --noEmit` -Expected: PASS. - -```bash -git -C game-description-language add src/types/vortex-api.d.ts -git -C game-description-language commit -m "feat(types): declare fs.statAsync and api.showDialog in stub" -``` - ---- - -### Task A5: Runtime — run the check and show the dialog - -**Files:** - -- Modify: `game-description-language/src/runtime/vortex-shim.ts` (add type, `registerGame` trailing param, setup logic, helper) -- Test: `game-description-language/tests/require-files.test.ts` (append) - -- [ ] **Step 1: Write the failing runtime tests** - -Append to `tests/require-files.test.ts`: - -```ts -import { GdlRuntime } from "../src/runtime/index.js"; -import { createFakeContext } from "../src/runtime/testing/index.js"; -import type { IExtensionContext } from "vortex-api"; -import { vi } from "vitest"; - -const RT_DECL = { id: "g", name: "G", executable: "G.exe", requiredFiles: ["G.exe"] }; -const RT_STORES = [{ id: "steam", value: "1" }]; -const RT_CTX = { bindings: [] }; -const RT_MODTYPES: never[] = []; -const RT_RF = { - files: ["${installPath}/UnityModManager/UnityModManager.dll"], - prompt: { - title: "Action required", - message: "Install UMM", - link: { label: "Get UMM", url: "https://www.nexusmods.com/site/mods/21" }, - }, -}; - -const dialogMock = (h: ReturnType) => - (h.context as unknown as { api: { showDialog: ReturnType } }).api.showDialog; - -describe("runtime: setup.requireFiles", () => { - beforeEach(() => vi.clearAllMocks()); - - it("shows the prompt when a required file is missing", async () => { - const { fs } = await import("vortex-api"); - vi.mocked(fs.statAsync).mockRejectedValue(new Error("ENOENT")); - const h = createFakeContext(); - const runtime = new GdlRuntime(h.context as IExtensionContext); - runtime.registerGame( - RT_DECL, - RT_STORES, - RT_CTX, - RT_MODTYPES, - [], - {}, - [], - [], - {}, - [], - RT_RF, - ); - const g = h.registered.game!; - await g.setup!({ path: "/games/g", store: "steam" }); - expect(dialogMock(h)).toHaveBeenCalledTimes(1); - expect(dialogMock(h).mock.calls[0][1]).toBe("Action required"); - }); - - it("stays silent when all required files exist", async () => { - const { fs } = await import("vortex-api"); - vi.mocked(fs.statAsync).mockResolvedValue({ isDirectory: () => false }); - const h = createFakeContext(); - const runtime = new GdlRuntime(h.context as IExtensionContext); - runtime.registerGame( - RT_DECL, - RT_STORES, - RT_CTX, - RT_MODTYPES, - [], - {}, - [], - [], - {}, - [], - RT_RF, - ); - await h.registered.game!.setup!({ path: "/games/g", store: "steam" }); - expect(dialogMock(h)).not.toHaveBeenCalled(); - }); -}); -``` - -- [ ] **Step 2: Run to verify failure** - -Run: `cd game-description-language && pnpm exec vitest run tests/require-files.test.ts -t "runtime: setup.requireFiles"` -Expected: FAIL (`registerGame` ignores the 11th arg; no dialog). - -- [ ] **Step 3: Add the `RequireFilesSpec` type** - -In `src/runtime/vortex-shim.ts`, near the other exported interfaces (e.g. after `EventHooks`), add: - -```ts -export interface RequireFilesSpec { - files: string[]; - prompt: { - title: string; - message: string; - link?: { label: string; url: string }; - }; -} -``` - -- [ ] **Step 4: Add the trailing `registerGame` parameter** - -Extend the `registerGame` signature. After the existing `diagnostics: IModHealthCheck[] = [],` parameter, add: - -```ts - requireFiles?: RequireFilesSpec, -``` - -- [ ] **Step 5: Run the check inside `game.setup`** - -Replace the existing setup block: - -```ts -if (setupDirs.length > 0) { - game.setup = async (discovery: IDiscoveryResult) => { - const { fs } = await import("vortex-api"); - const facts = this.factsFromDiscovery(discovery); - this.cachedFacts = facts; - this.resolvedCtx = resolveContext(contextSpec, facts); - if (discovery.store) this.discoveredStore = discovery.store; - for (const tpl of setupDirs) { - const path = interpolate(tpl, this.resolvedCtx); - await fs.ensureDirWritableAsync(path); - } - }; -} -``` - -with: - -```ts -if (setupDirs.length > 0 || requireFiles !== undefined) { - game.setup = async (discovery: IDiscoveryResult) => { - const { fs } = await import("vortex-api"); - const facts = this.factsFromDiscovery(discovery); - this.cachedFacts = facts; - this.resolvedCtx = resolveContext(contextSpec, facts); - if (discovery.store) this.discoveredStore = discovery.store; - for (const tpl of setupDirs) { - const path = interpolate(tpl, this.resolvedCtx); - await fs.ensureDirWritableAsync(path); - } - if (requireFiles !== undefined) { - await this.runRequireFilesCheck(requireFiles); - } - }; -} -``` - -- [ ] **Step 6: Add the `runRequireFilesCheck` method** - -Add this private method to the `GdlRuntime` class (e.g. just below `registerGame`): - -```ts - // Setup-time prerequisite check. Resolve each declared file template against - // the current context and stat it. If any are missing, show an informational - // dialog that points the user at a download. Non-fatal: it never rejects setup. - private async runRequireFilesCheck(spec: RequireFilesSpec): Promise { - const { fs, util } = await import('vortex-api'); - const ctx = this.resolvedCtx ?? ({} as ResolvedContext); - const resolved = spec.files.map((tpl) => interpolate(tpl, ctx)); - const present = await Promise.all( - resolved.map(async (p) => { - try { - await fs.statAsync(p); - return true; - } catch { - return false; - } - }), - ); - if (present.every(Boolean)) return; - - const actions: Array<{ label: string; action?: () => void }> = [{ label: 'Close' }]; - if (spec.prompt.link) { - const { label, url } = spec.prompt.link; - actions.push({ label, action: () => { void util.opn(url).catch(() => undefined); } }); - } - void this.api.api.showDialog('info', spec.prompt.title, { text: spec.prompt.message }, actions); - } -``` - -Note: `ResolvedContext` and `interpolate` are already imported at the top of this file. - -- [ ] **Step 7: Run to verify pass** - -Run: `cd game-description-language && pnpm exec vitest run tests/require-files.test.ts` -Expected: PASS (parser + validator + runtime). - -- [ ] **Step 8: Typecheck and commit** - -Run: `cd game-description-language && pnpm exec tsc --noEmit` -Expected: PASS. - -```bash -git -C game-description-language add src/runtime/vortex-shim.ts tests/require-files.test.ts -git -C game-description-language commit -m "feat(runtime): stat requireFiles and show download prompt in setup" -``` - ---- - -### Task A6: Codegen — emit the `requireFiles` literal - -**Files:** - -- Modify: `game-description-language/src/codegen/emit.ts` (build a literal near line 149; pass it as the 11th `registerGame` arg near line 264-267) -- Test: `game-description-language/tests/require-files.test.ts` (append) - -- [ ] **Step 1: Write the failing codegen tests** - -Append to `tests/require-files.test.ts`: - -```ts -import { emit } from "../src/codegen/emit.js"; - -describe("codegen: setup.requireFiles", () => { - const extOf = (yaml: string) => { - const doc = parseYaml(yaml, "rf.yaml"); - return emit(doc).find((f) => f.path.endsWith("extension.ts"))!.contents; - }; - - it("builds a nexus mod page URL from a mod target", () => { - const ext = extOf( - baseYaml( - ` files: - - \${installPath}/x.dll - prompt: - title: Action required - message: Install UMM - link: - label: Get UMM - mod: { domain: site, modId: 21 }`, - ), - ); - expect(ext).toContain("'https://www.nexusmods.com/site/mods/21'"); - expect(ext).toContain("Action required"); - }); - - it("passes a url target through unchanged", () => { - const ext = extOf( - baseYaml( - ` files: - - \${installPath}/x.dll - prompt: - title: T - message: M - link: - label: L - url: https://example.com/umm`, - ), - ); - expect(ext).toContain("'https://example.com/umm'"); - }); - - it("emits undefined when no requireFiles is declared", () => { - const ext = extOf(`gdl: 1 -game: - id: g - name: G - executable: G.exe - requiredFiles: [G.exe] -stores: - steam: "1" -setup: - ensureDirs: - - \${installPath}/Mods`); - // The 11th registerGame argument is the requireFiles literal. - expect(ext).toMatch(/\],\s*undefined,\s*\);/); - }); -}); -``` - -- [ ] **Step 2: Run to verify failure** - -Run: `cd game-description-language && pnpm exec vitest run tests/require-files.test.ts -t "codegen: setup.requireFiles"` -Expected: FAIL (no requireFiles arg emitted). - -- [ ] **Step 3: Build the literal** - -In `src/codegen/emit.ts`, after the `setupDirsLines` definition (around line 151), add: - -```ts -const requireFilesLit = (() => { - const rf = doc.setup?.requireFiles; - if (!rf) return "undefined"; - const filesLit = `[${rf.files.map(sq).join(", ")}]`; - let linkLit = ""; - if (rf.prompt.link) { - const t = rf.prompt.link.target; - const url = - t.kind === "url" ? t.url : `https://www.nexusmods.com/${t.domain}/mods/${t.modId}`; - linkLit = `, link: { label: ${sq(rf.prompt.link.label)}, url: ${sq(url)} }`; - } - return `{ files: ${filesLit}, prompt: { title: ${sq(rf.prompt.title)}, message: ${sq(rf.prompt.message)}${linkLit} } }`; -})(); -``` - -- [ ] **Step 4: Pass it as the 11th `registerGame` argument** - -In the `extension` template string, the `registerGame(...)` call currently ends with the diagnostics array: - -```ts - [ -${diagnosticsLines} - ], - ); -``` - -Change it to append the literal: - -```ts - [ -${diagnosticsLines} - ], - ${requireFilesLit}, - ); -``` - -- [ ] **Step 5: Run to verify pass** - -Run: `cd game-description-language && pnpm exec vitest run tests/require-files.test.ts` -Expected: PASS (all parser + validator + runtime + codegen cases). - -- [ ] **Step 6: Typecheck and commit** - -Run: `cd game-description-language && pnpm exec tsc --noEmit` - -```bash -git -C game-description-language add src/codegen/emit.ts tests/require-files.test.ts -git -C game-description-language commit -m "feat(codegen): emit setup.requireFiles into registerGame call" -``` - ---- - -### Task A7: Rebuild GDL dist and run the full suite - -**Files:** none (build + verify) - -- [ ] **Step 1: Full test suite** - -Run: `cd game-description-language && pnpm test` -Expected: PASS (baseline suite plus the new `require-files.test.ts` cases). No regressions. - -- [ ] **Step 2: Rebuild the toolchain dist** - -The Vortex game build reuses `game-description-language/dist` and only rebuilds it when `dist/cli.js` is absent. Rebuild it now so Phase B compiles against the new feature: - -```bash -cd game-description-language && pnpm build -``` - -Expected: build succeeds; `dist/cli.js`, `dist/commands/build.js` regenerated. - -- [ ] **Step 3: Confirm the branch is clean** - -Run: `git -C game-description-language status --porcelain` -Expected: empty (all feature changes committed; `dist/` is git-ignored in the submodule, confirm with `git -C game-description-language status` that no unexpected files are staged). - ---- - -# Phase B: Convert the two Pathfinder extensions - -All Phase B work is in the Vortex repo on branch `halgari/pathfinder-to-gdl` (already checked out). Run commands from `/c/oss/Vortex`. - -### Task B1: Convert Pathfinder: Kingmaker - -**Files:** - -- Create: `extensions/games/game-pathfinderkingmaker/game.yaml` -- Create: `extensions/games/game-pathfinderkingmaker/build.mjs` -- Create: `extensions/games/game-pathfinderkingmaker/vitest.config.ts` -- Rewrite: `extensions/games/game-pathfinderkingmaker/package.json` -- Move: `assets/gameart.jpg` to `gameart.jpg` (extension root) -- Delete: `src/index.js`, `assets/` (with `umm.png`), `tsconfig.tsbuildinfo` - -- [ ] **Step 1: Move the logo to the extension root and remove old files** - -Run: - -```bash -cd /c/oss/Vortex/extensions/games/game-pathfinderkingmaker -git mv assets/gameart.jpg gameart.jpg -git rm src/index.js assets/umm.png tsconfig.tsbuildinfo -rmdir assets 2>/dev/null || true -``` - -Expected: `gameart.jpg` now at the extension root; `src/`, `assets/` gone. - -- [ ] **Step 2: Write `game.yaml`** - -Create `extensions/games/game-pathfinderkingmaker/game.yaml`: - -```yaml -gdl: 1 -version: 0.2.0 - -game: - id: pathfinderkingmaker - name: "Pathfinder: Kingmaker" - executable: Kingmaker.exe - requiredFiles: [Kingmaker.exe] - logo: gameart.jpg - author: m0nster - nexusDomain: pathfinderkingmaker - # All Kingmaker mods deploy under the game's Mods folder (Unity Mod Manager). - queryModPath: Mods - -stores: - steam: "640820" - -setup: - ensureDirs: - - ${installPath}/Mods - requireFiles: - files: - - ${installPath}/UnityModManager/UnityModManager.dll - prompt: - title: Action required - message: >- - You must install Unity Mod Manager to use mods with Pathfinder: Kingmaker. - link: - label: Go to the Unity Mod Manager page - mod: { domain: site, modId: 21 } -``` - -- [ ] **Step 3: Write `build.mjs`** - -Create `extensions/games/game-pathfinderkingmaker/build.mjs` (identical to the X Rebirth GDL build entry): - -```js -import * as path from "node:path"; - -import { buildGdlExtension } from "../../../scripts/build-gdl-extension.mjs"; - -// This extension is described declaratively in game.yaml and compiled by the -// Game Description Language (GDL) toolchain into a Vortex-loadable dist/index.js. -await buildGdlExtension(path.resolve(import.meta.dirname)); -``` - -- [ ] **Step 4: Write `vitest.config.ts`** - -Create `extensions/games/game-pathfinderkingmaker/vitest.config.ts` (copied from X Rebirth so `pnpm test` runs cleanly even with no local tests): - -```ts -import { createRequire } from "node:module"; - -import { mergeConfig, defineConfig } from "vitest/config"; - -import baseConfig from "../../../vitest.base.config"; - -const require_ = createRequire(import.meta.url); -const VORTEX_API_MOCK = require_.resolve("@vortex/extension-test-mocks"); - -export default mergeConfig( - baseConfig, - defineConfig({ - resolve: { - alias: [{ find: /^@nexusmods\/vortex-api$/, replacement: VORTEX_API_MOCK }], - }, - test: { - environment: "node", - include: ["src/**/*.test.ts"], - }, - }), -); -``` - -- [ ] **Step 5: Rewrite `package.json`** - -Overwrite `extensions/games/game-pathfinderkingmaker/package.json`: - -```json -{ - "name": "game-pathfinderkingmaker", - "version": "0.2.0", - "description": "Support for Pathfinder: Kingmaker", - "scripts": { - "build": "node build.mjs", - "test": "pnpm exec vitest run --passWithNoTests" - }, - "author": "m0nster", - "license": "GPL-3.0", - "type": "commonjs", - "private": true, - "config": { - "game": "Pathfinder: Kingmaker" - }, - "devDependencies": { - "@nexusmods/vortex-api": "workspace:*", - "@vortex/extension-test-mocks": "workspace:*" - }, - "nx": { - "tags": ["vortex:extension"], - "targets": { - "build": { - "inputs": ["default", "typescript", "vortex-api"] - } - } - } -} -``` - -- [ ] **Step 6: Install workspace deps (new devDependency added)** - -Run (from `/c/oss/Vortex`): `pnpm install` -Expected: succeeds; links `@vortex/extension-test-mocks` into the package. - -- [ ] **Step 7: Build the extension** - -Run: `pnpm --filter game-pathfinderkingmaker run build` -Expected: GDL compiles `game.yaml`. Output: `dist/index.js`, `dist/index.js.map`, `dist/info.json`, `dist/gameart.jpg`. - -- [ ] **Step 8: Verify the build output** - -Run: - -```bash -ls extensions/games/game-pathfinderkingmaker/dist/ -cat extensions/games/game-pathfinderkingmaker/dist/info.json -grep -c "https://www.nexusmods.com/site/mods/21" extensions/games/game-pathfinderkingmaker/dist/index.js -``` - -Expected: `dist/` contains `index.js`, `info.json`, `gameart.jpg`; `info.json` has `id`/`name`/`version 0.2.0`; the grep prints `1` (the UMM page URL is baked into the bundle). - -- [ ] **Step 9: Run test + lint + format for the package** - -Run: - -```bash -pnpm --filter game-pathfinderkingmaker run test -pnpm exec eslint extensions/games/game-pathfinderkingmaker --max-warnings 0 || true -pnpm exec oxfmt extensions/games/game-pathfinderkingmaker -``` - -Expected: test passes with no test files (`--passWithNoTests`). Resolve any lint errors GDL extensions are expected to satisfy (the `|| true` is only to surface output; fix real errors). - -- [ ] **Step 10: Commit** - -```bash -cd /c/oss/Vortex -git add extensions/games/game-pathfinderkingmaker/ -git commit -m "Convert Pathfinder: Kingmaker extension to GDL - -Replace the imperative index.js with a declarative game.yaml. Drop the -modtype-umm dependency, registry probe, Bluebird, and platform guards. -UMM presence is checked via the new setup.requireFiles block, which prompts -the user to the Unity Mod Manager page when the loader is absent." -``` - ---- - -### Task B2: Convert Pathfinder: Wrath of the Righteous - -**Files:** - -- Create: `extensions/games/game-pathfinderwrathoftherighteous/game.yaml` -- Create: `extensions/games/game-pathfinderwrathoftherighteous/vitest.config.ts` -- Rewrite: `extensions/games/game-pathfinderwrathoftherighteous/build.mjs`, `package.json` -- Move: `assets/gameart.jpg` to `gameart.jpg` -- Delete: `src/index.ts`, `assets/` (with `umm.png`) - -- [ ] **Step 1: Move the logo and remove old files** - -Run: - -```bash -cd /c/oss/Vortex/extensions/games/game-pathfinderwrathoftherighteous -git mv assets/gameart.jpg gameart.jpg -git rm src/index.ts assets/umm.png -rmdir assets 2>/dev/null || true -``` - -- [ ] **Step 2: Write `game.yaml`** - -Create `extensions/games/game-pathfinderwrathoftherighteous/game.yaml`: - -```yaml -gdl: 1 -version: 1.0.1 - -game: - id: pathfinderwrathoftherighteous - name: "Pathfinder: Wrath of the Righteous" - executable: Wrath.exe - requiredFiles: [Wrath.exe] - logo: gameart.jpg - author: Black Tree Gaming Ltd. - nexusDomain: pathfinderwrathoftherighteous - queryModPath: Mods - -stores: - steam: "1184370" - gog: "1207187357" - -# Reads the build version from Version.info. The original extension split the -# file on spaces and took the 4th token; the regex captures that same token. -discovery: - version: - file: ${installPath}/Wrath_Data/StreamingAssets/Version.info - regex: '^(?:\S+\s+){3}(\S+)' - -setup: - ensureDirs: - - ${installPath}/Mods - requireFiles: - files: - - ${installPath}/UnityModManager/UnityModManager.dll - prompt: - title: Action required - message: >- - You must install Unity Mod Manager to use mods with Pathfinder: Wrath of - the Righteous. - link: - label: Go to the Unity Mod Manager page - mod: { domain: site, modId: 21 } -``` - -- [ ] **Step 3: Overwrite `build.mjs`** - -Replace `extensions/games/game-pathfinderwrathoftherighteous/build.mjs` with the GDL build entry: - -```js -import * as path from "node:path"; - -import { buildGdlExtension } from "../../../scripts/build-gdl-extension.mjs"; - -// This extension is described declaratively in game.yaml and compiled by the -// Game Description Language (GDL) toolchain into a Vortex-loadable dist/index.js. -await buildGdlExtension(path.resolve(import.meta.dirname)); -``` - -- [ ] **Step 4: Write `vitest.config.ts`** - -Create `extensions/games/game-pathfinderwrathoftherighteous/vitest.config.ts` with the same contents as Task B1 Step 4. - -- [ ] **Step 5: Rewrite `package.json`** - -Overwrite `extensions/games/game-pathfinderwrathoftherighteous/package.json`: - -```json -{ - "name": "game-pathfinderwrathoftherighteous", - "version": "1.0.1", - "description": "Support for Pathfinder: Wrath of the Righteous", - "scripts": { - "build": "node build.mjs", - "test": "pnpm exec vitest run --passWithNoTests" - }, - "author": "Black Tree Gaming Ltd.", - "license": "GPL-3.0", - "type": "commonjs", - "private": true, - "config": { - "game": "Pathfinder: Wrath of the Righteous" - }, - "devDependencies": { - "@nexusmods/vortex-api": "workspace:*", - "@vortex/extension-test-mocks": "workspace:*" - }, - "nx": { - "tags": ["vortex:extension"], - "targets": { - "build": { - "inputs": ["default", "typescript", "vortex-api"] - } - } - } -} -``` - -- [ ] **Step 6: Install, build, verify** - -Run (from `/c/oss/Vortex`): - -```bash -pnpm install -pnpm --filter game-pathfinderwrathoftherighteous run build -ls extensions/games/game-pathfinderwrathoftherighteous/dist/ -cat extensions/games/game-pathfinderwrathoftherighteous/dist/info.json -grep -c "https://www.nexusmods.com/site/mods/21" extensions/games/game-pathfinderwrathoftherighteous/dist/index.js -``` - -Expected: `dist/index.js`, `dist/info.json` (version `1.0.1`), `dist/gameart.jpg`; grep prints `1`. Confirm the bundle also references `Version.info` (the version regex): `grep -c "Version.info" .../dist/index.js` prints `1`. - -- [ ] **Step 7: Test + lint + format** - -Run: - -```bash -pnpm --filter game-pathfinderwrathoftherighteous run test -pnpm exec oxfmt extensions/games/game-pathfinderwrathoftherighteous -``` - -Expected: test passes (`--passWithNoTests`); format clean. - -- [ ] **Step 8: Commit** - -```bash -git add extensions/games/game-pathfinderwrathoftherighteous/ -git commit -m "Convert Pathfinder: Wrath of the Righteous extension to GDL - -Replace the imperative index.ts with a declarative game.yaml. Drop the -modtype-umm/ummAddGame integration, move version detection to a declarative -discovery.version (Version.info) block, and add the setup.requireFiles UMM -prompt. WotR no longer auto-downloads UMM (accepted regression)." -``` - ---- - -### Task B3: Bump the submodule pointer and final verification - -**Files:** - -- Modify: the `game-description-language` submodule gitlink (Vortex records the new commit) - -- [ ] **Step 1: Stage the submodule pointer** - -The Vortex working tree now sees `game-description-language` at the new `feat/setup-require-files` commit. Stage it: - -```bash -cd /c/oss/Vortex -git add game-description-language -git status -``` - -Expected: `game-description-language` shows as a modified submodule (new commit). - -- [ ] **Step 2: Rebuild both games against the bumped submodule from a clean dist** - -Run: - -```bash -rm -rf extensions/games/game-pathfinderkingmaker/dist extensions/games/game-pathfinderwrathoftherighteous/dist -pnpm --filter game-pathfinderkingmaker run build -pnpm --filter game-pathfinderwrathoftherighteous run build -``` - -Expected: both build cleanly against the current submodule dist. - -- [ ] **Step 3: Commit the submodule bump** - -```bash -git commit -m "chore: bump game-description-language submodule for setup.requireFiles" -``` - -- [ ] **Step 4: Final affected-package checks** - -Run: - -```bash -pnpm --filter game-pathfinderkingmaker run test -pnpm --filter game-pathfinderwrathoftherighteous run test -pnpm exec oxfmt extensions/games/game-pathfinderkingmaker extensions/games/game-pathfinderwrathoftherighteous -``` - -Expected: all green. - -- [ ] **Step 5: Independent review (recommended)** - -Spawn a review subagent (clean context, sonnet) to verify each `game.yaml` is a faithful replacement of the original discovery paths (Steam/GOG ids, exe, Mods path, WotR version source) and that the dropped behaviors match the approved design. Fix anything it surfaces before opening a PR. - ---- - -## Notes for the implementer - -- The GDL feature lives in a separate repo (`Nexus-Mods/game-description-language`). Pushing `feat/setup-require-files` and opening its PR is a separate step from this plan; the Vortex branch only records the submodule commit. Do not push or open PRs unless asked. -- `buildGdlExtension` caches the submodule build. If a game build ever picks up stale GDL behavior, rebuild the submodule dist: `cd game-description-language && pnpm build`. -- The UMM marker path `${installPath}/UnityModManager/UnityModManager.dll` is a best-effort path-based check. Verify it against a real UMM-patched Pathfinder install; the value is a one-line `game.yaml` edit. -- Keep `game.yaml`'s `version:` in sync with `package.json`. The build steps assert the emitted `info.json` version (0.2.0 / 1.0.1); if it comes out as `0.0.0`, trace how `build.ts` sources `extensionVersion` and adjust (mirror what X Rebirth does, which sets both). diff --git a/docs/superpowers/specs/2026-06-17-pathfinder-gdl-conversion-design.md b/docs/superpowers/specs/2026-06-17-pathfinder-gdl-conversion-design.md deleted file mode 100644 index 28d3c6843f..0000000000 --- a/docs/superpowers/specs/2026-06-17-pathfinder-gdl-conversion-design.md +++ /dev/null @@ -1,245 +0,0 @@ -# Pathfinder extensions to GDL: design - -Date: 2026-06-17 -Branch: `halgari/pathfinder-to-gdl` (off `halgari/games-to-gdl-1`) - -## Goal - -Convert the two Owlcat Pathfinder game extensions to the Game Description -Language (GDL), the same declarative toolchain the X Rebirth extension now uses. - -- `extensions/games/game-pathfinderkingmaker` (currently `src/index.js`) -- `extensions/games/game-pathfinderwrathoftherighteous` (currently `src/index.ts`) - -Both become pure `game.yaml` with no `src/hooks.ts`. One new GDL feature is -added in the `game-description-language` submodule to cover the only behaviour -that GDL cannot express today. - -## What the two extensions do today - -| | Kingmaker | Wrath of the Righteous | -| --------------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | -| Stores | Steam `640820` | Steam `1184370`, GOG `1207187357` | -| Mods path | `Mods/` | `Mods/` | -| `requireExtension("modtype-umm")` | yes | yes | -| UMM registration | none; setup shows a manual "install UMM" dialog after a registry probe | `context.once(() => api.ext.ummAddGame({ gameId, autoDownloadUMM: true }))` | -| getGameVersion | none | reads `Wrath_Data/StreamingAssets/Version.info`, takes the 4th space-delimited token | -| Installers / modTypes | none | none | - -Neither game registers a custom installer or mod type. Game mods deploy to the -`Mods/` folder through Vortex's default path. The `umm` mod type (UMM the tool) -comes from the separate `modtype-umm` extension and only activates for a game -once that game has called `ummAddGame`. Kingmaker never calls it, so the `umm` -mod type is inert for Kingmaker today. - -## Key decisions - -These were settled during brainstorming. - -1. **Unify both games on a file-check plus download prompt.** Drop the - `modtype-umm` integration from both games. WotR loses its `ummAddGame` - auto-download and `umm` mod-type activation. This is an accepted behaviour - regression for WotR in exchange for both games becoming self-contained - declarative extensions. Game mods continue to deploy to `Mods/` exactly as - before; the change only affects how the UMM tool itself is obtained (a prompt - instead of auto-download). - -2. **`requireExtension("modtype-umm")` is dropped from both.** Once neither game - calls `ummAddGame`, the dependency is inert (the `umm` mod type never matches - either game), so it carries no behaviour. GDL therefore needs no - `requireExtension` support and no general init hook. - -3. **The file lookup is purely path based.** No registry reads. GDL deliberately - removed all `winapi` access and we keep it that way. For UMM this shifts the - meaning of the check from "is the UMM tool installed anywhere on the system" - (the old registry probe) to "is UMM set up in this game's folder." Accepted. - -4. **The prompt's download target opens a page, it does not silently install.** - The target is either a Nexus mod reference (`domain` + `modId`) that opens - `https://www.nexusmods.com//mods/`, or a plain `url`. Both - resolve to a single `util.opn(...)` call. A true one-click install would - require pinning a `fileId` per release, which is maintenance churn we avoid. - -## New GDL feature: `setup.requireFiles` - -GDL's `setup:` block today supports only `ensureDirs`. We extend it with an -optional `requireFiles` step that runs during the game's `setup` lifecycle, -right after `ensureDirs`. - -### YAML shape - -```yaml -setup: - ensureDirs: - - ${installPath}/Mods - requireFiles: - files: - - ${installPath}/UnityModManager/UnityModManager.dll - prompt: - title: Action required - message: You must install Unity Mod Manager to use mods with this game. - link: - label: Go to the Unity Mod Manager page - mod: { domain: site, modId: 21 } # or: url: https://example.com/... -``` - -### Field rules - -- `requireFiles` is optional inside `setup`. -- `files` is a non-empty list of path templates, interpolated against the - runtime context (`${installPath}`, etc.). The validator rejects an empty list. -- `prompt.title` and `prompt.message` are required when `requireFiles` is present. -- `prompt.link` is optional. - - `link.label` is the button text (required when `link` is present). - - Exactly one of `link.mod` or `link.url` must be set. - - `link.mod` is `{ domain: , modId: }`. - - `link.url` is a string. - -### Runtime semantics - -Implemented in the runtime shim's generated `game.setup`, after `ensureDirs`: - -1. Resolve every `files` template against the resolved context and `fs.statAsync` - each one. -2. If all exist, do nothing. -3. If any are missing, call `api.showDialog`: - - Type `info`, title `prompt.title`, body text `prompt.message`. - - Buttons: a `Cancel`/`Close` button, plus (when `link` is present) a button - labelled `link.label` whose action calls `util.opn(targetUrl)`, where - `targetUrl` is `link.url` or `https://www.nexusmods.com//mods/` - built from `link.mod`. -4. The step is informational. It does not reject `setup`. - -The original Kingmaker code rejected `setup` with `UserCanceled` after the -dialog. We drop that quirk; a passive prompt that lets management proceed is -cleaner. This is the one intentional behaviour change beyond the registry to -path shift. - -### Where it lives in the toolchain - -The feature is implemented in the `game-description-language` submodule (its own -repo, `Nexus-Mods/game-description-language`, currently on `main`), touching: - -- `src/parser/ast.ts`: add `requireFiles?` to `SetupNode`, plus the supporting - node types for `files`, `prompt`, and `link`. -- `src/parser/index.ts`: parse the new keys under `setup`. -- `src/schema/validator.ts`: enforce the field rules above. -- `src/codegen/emit.ts` and `src/codegen/lifecycle-emit.ts`: thread the parsed - `requireFiles` data into the generated extension and `game.setup`. -- `src/runtime/vortex-shim.ts`: extend the generated `game.setup` to run the - stat-and-prompt logic. -- Tests in the GDL repo: parser, validator, codegen, and a runtime test that the - generated `setup` stats the listed files and fires the dialog when one is - missing. - -The Vortex branch then bumps the submodule pointer, matching the existing -pattern (the X Rebirth conversion landed GDL features as PR #2 in that repo, -followed by "bump game-description-language submodule" commits here). - -### Alternatives considered - -- **A new top-level `prerequisites:` block** instead of nesting under `setup`. - More general, but the only consumer right now is setup-time, so the extra - schema surface is not justified (YAGNI). Rejected. -- **A diagnostic / health check** using GDL's existing `diagnostics:` block. A - health check is a passive warning surface, so it cannot present the actionable - "go get UMM" button the original behaviour has. Rejected. -- **A registry-based lookup option** for faithful UMM detection. Rejected to - keep GDL free of `winapi` (decision 3). -- **One-click install via `nexus-download` / `nxm://` URL.** Requires a pinned - `fileId` per release. Rejected for the maintenance churn (decision 4). - -## Converted extensions - -Neither game needs a `src/hooks.ts`. Both become a single `game.yaml` plus the -GDL plumbing files (`package.json`, `build.mjs`, `tsconfig.json`, -`vitest.config.ts`), mirroring `game-xrebirth`. The `gameart.jpg` logos convert -to `gameart.webp`. - -### Kingmaker `game.yaml` (shape) - -```yaml -gdl: 1 -version: - -game: - id: pathfinderkingmaker - name: "Pathfinder: Kingmaker" - executable: Kingmaker.exe - requiredFiles: [Kingmaker.exe] - logo: gameart.webp - nexusDomain: pathfinderkingmaker - queryModPath: Mods - -stores: - steam: "640820" - -setup: - ensureDirs: - - ${installPath}/Mods - requireFiles: - files: - - ${installPath}/UnityModManager/UnityModManager.dll - prompt: - title: Action required - message: You must install Unity Mod Manager to use mods with Pathfinder: Kingmaker. - link: - label: Go to the Unity Mod Manager page - mod: { domain: site, modId: 21 } - -tests: - corpus: nexus -``` - -`environment.SteamAPPId` and `details.steamAppId` auto-derive from `stores.steam`, -so they are not set explicitly. Dropped from the original: the registry helpers, -Bluebird, the `process.platform` guard, and `requireExtension`. - -### WotR `game.yaml` (shape) - -Same as Kingmaker, with these differences: - -```yaml -game: - id: pathfinderwrathoftherighteous - name: "Pathfinder: Wrath of the Righteous" - executable: Wrath.exe - requiredFiles: [Wrath.exe] - nexusDomain: pathfinderwrathoftherighteous - queryModPath: Mods - -stores: - steam: "1184370" - gog: "1207187357" - -discovery: - version: - file: ${installPath}/Wrath_Data/StreamingAssets/Version.info - regex: '^(?:\S+\s+){3}(\S+)' # 4th space-delimited token, == old split(" ")[3] - -setup: - ensureDirs: - - ${installPath}/Mods - requireFiles: - # same UMM check as Kingmaker -``` - -Dropped from the original: `requireExtension`, the `ummAddGame` registration -(decision 1), and the imperative `getGameVersion` (now declarative via -`discovery.version`). - -## Testing - -- The new GDL feature is unit tested in the GDL repo (parser, validator, - codegen, runtime), including a runtime case that proves the dialog fires when a - required file is absent and stays silent when all are present. -- Each game opts into `tests: { corpus: nexus }` so the installer and deploy path - runs against real Nexus mod manifests, the same harness X Rebirth uses. The - corpus does not exercise `requireFiles`, which is setup-time only. - -## Open items to confirm during implementation - -- The exact UMM marker file path under the game directory. The `game.yaml` value - is trivially tunable; verify it against a real UMM-patched Pathfinder layout. -- Whether `version` should be sourced from each `package.json` (as X Rebirth - does) or pinned in `game.yaml`. From 669b452ab8b5a2e06ebb737ccc2053270a2d17aa Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Mon, 22 Jun 2026 07:28:26 -0700 Subject: [PATCH 9/9] Convert Pathfinder game art to webp --- .../games/game-pathfinderkingmaker/game.yaml | 2 +- .../games/game-pathfinderkingmaker/gameart.jpg | Bin 78239 -> 0 bytes .../games/game-pathfinderkingmaker/gameart.webp | Bin 0 -> 45428 bytes .../game.yaml | 2 +- .../gameart.jpg | Bin 58013 -> 0 bytes .../gameart.webp | Bin 0 -> 47022 bytes 6 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 extensions/games/game-pathfinderkingmaker/gameart.jpg create mode 100644 extensions/games/game-pathfinderkingmaker/gameart.webp delete mode 100644 extensions/games/game-pathfinderwrathoftherighteous/gameart.jpg create mode 100644 extensions/games/game-pathfinderwrathoftherighteous/gameart.webp diff --git a/extensions/games/game-pathfinderkingmaker/game.yaml b/extensions/games/game-pathfinderkingmaker/game.yaml index 0b8424a034..4954b10803 100644 --- a/extensions/games/game-pathfinderkingmaker/game.yaml +++ b/extensions/games/game-pathfinderkingmaker/game.yaml @@ -6,7 +6,7 @@ game: name: "Pathfinder: Kingmaker" executable: Kingmaker.exe requiredFiles: [Kingmaker.exe] - logo: gameart.jpg + logo: gameart.webp author: m0nster nexusDomain: pathfinderkingmaker # Unity Mod Manager mods deploy under the game's Mods folder. diff --git a/extensions/games/game-pathfinderkingmaker/gameart.jpg b/extensions/games/game-pathfinderkingmaker/gameart.jpg deleted file mode 100644 index 74be91e2421aba79a6aa9b1ed6637bff73cb50dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78239 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 diff --git a/extensions/games/game-pathfinderkingmaker/gameart.webp b/extensions/games/game-pathfinderkingmaker/gameart.webp new file mode 100644 index 0000000000000000000000000000000000000000..7472e2ea8422d98ec5231844f3331f1e621a3c71 GIT binary patch literal 45428 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 >|gK8&2(X&d898cy_yK^6k_D#Zf^w3WNC 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 Ap#T5? literal 0 HcmV?d00001 diff --git a/extensions/games/game-pathfinderwrathoftherighteous/game.yaml b/extensions/games/game-pathfinderwrathoftherighteous/game.yaml index 9cb04dcebd..e1af354225 100644 --- a/extensions/games/game-pathfinderwrathoftherighteous/game.yaml +++ b/extensions/games/game-pathfinderwrathoftherighteous/game.yaml @@ -6,7 +6,7 @@ game: name: "Pathfinder: Wrath of the Righteous" executable: Wrath.exe requiredFiles: [Wrath.exe] - logo: gameart.jpg + logo: gameart.webp author: Black Tree Gaming Ltd. nexusDomain: pathfinderwrathoftherighteous # Unity Mod Manager mods deploy under the game's Mods folder. diff --git a/extensions/games/game-pathfinderwrathoftherighteous/gameart.jpg b/extensions/games/game-pathfinderwrathoftherighteous/gameart.jpg deleted file mode 100644 index 2da38b6fcc9aa170c79ea8f4119814c4ff85c1bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58013 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 literal 0 HcmV?d00001