Node 24 + TypeScript PVF browser for the files under fixtures/.
- Root:
pnpm workspace - App:
apps/pvf-explorer - Runtime: Node.js native TypeScript execution, no bundler / transpiler
pnpm install
pnpm dev
pnpm bench
pnpm lint
pnpm lint:fix
pnpm format
pnpm format:check
pnpm spellcheck
pnpm typecheck
pnpm check
pnpm testThe local explorer starts at http://127.0.0.1:4318.
The repository now has a workspace-based mod pipeline system:
- shared runtime and pipeline helpers live in
packages/pvf-mod - individual mods live in
mods/* - the pipeline registry lives in
mods/registry.ts - named pipeline configs live in
mods/pipelines.ts - the CLI entrypoint lives in
apps/pvf-mod-cli
example_wild_strawberry_hp_up: changes Wild Strawberry HP recovery from60to600soldoros_doll: prepares the Soldoros doll APC and updatesaicharacter.lst2_3_choro_partset_skill_up: generates the merged Choro support equipment overlays and consumes the prerequisite doll APC
wild-strawberry-only: runs only the Wild Strawberry example moddemo: runsexample_wild_strawberry_hp_up -> soldoros_doll -> 2_3_choro_partset_skill_up
demo is the current default pipeline.
pnpm --filter pvf-mod-cli start listThis runs the selected pipeline in order, writes the final merged overlays to a directory, and emits a manifest JSON file.
pnpm --filter pvf-mod-cli start build --pipeline demoBy default this writes to out/<pipeline-id>/ and writes manifest.json in that directory.
Useful flags:
--pipeline <id>: choose a named pipeline frommods/pipelines.ts--archive <path>: read from a different source PVF instead offixtures/Script.pvf--out <dir>: override the overlay output directory--manifest-out <path>: override the manifest output path--text-profile simplified|traditional: choose rendered text profile
Example:
pnpm --filter pvf-mod-cli start build \
--pipeline wild-strawberry-only \
--out ./out/wild-strawberry \
--manifest-out ./out/wild-strawberry/manifest.jsonThis runs the selected pipeline in order and writes a new PVF file with all overlays applied.
pnpm --filter pvf-mod-cli start apply --pipeline demoBy default this writes to out/<pipeline-id>.pvf and also writes <output>.manifest.json.
Useful flags:
--pipeline <id>: choose a named pipeline--archive <path>: input PVF path--pvf-out <path>: output PVF path--manifest-out <path>: manifest output path--text-profile simplified|traditional: rendered text profile
Example:
pnpm --filter pvf-mod-cli start apply \
--pipeline demo \
--pvf-out ./out/demo.pvf \
--manifest-out ./out/demo.manifest.jsonIf you want to test a temporary sequence without editing mods/pipelines.ts, pass repeated --mod flags. The order of --mod flags is the execution order.
pnpm --filter pvf-mod-cli start build \
--pipeline adhoc-preview \
--mod example_wild_strawberry_hp_up \
--mod soldoros_doll \
--mod 2_3_choro_partset_skill_up- Create a new folder in
mods/<your_mod>/. - Export a
PvfRegisteredModfromsrc/index.ts. - Keep the mod focused on patch logic only. Do not put standalone CLI or manifest writing logic in the mod package.
- Add the mod to
mods/registry.ts. - Add it to a named pipeline in
mods/pipelines.ts, or run it ad hoc with repeated--mod.
The runtime guarantees that mods run sequentially, and mod n + 1 reads the merged final result produced by mods 1..n.
pnpm install --frozen-lockfileThis installs dependencies, prepares the local fixture if needed, and installs the Git hooks via husky.
- Make your changes.
- Run
pnpm formatif you touched multiple files or changed layout-heavy code. - Run
pnpm checkbefore pushing. - Run
pnpm testif your change can affect behavior.
pnpm lint: runseslintacross the repo.pnpm lint:fix: applies auto-fixable ESLint changes.pnpm format: formats supported files withdprint.pnpm format:check: verifies formatting without changing files.pnpm spellcheck: runscspellon source and docs.pnpm typecheck: runs workspace TypeScript checks.pnpm check: the main pre-push sanity check. It runs lint, format check, spellcheck, and typecheck together.
husky runs lint-staged on every commit. The lint-staged rules live in the root package.json. Only staged files are checked.
- staged
*.{ts,js,mjs,cjs}files run througheslint --fixanddprint fmt - staged
*.{json,jsonc,md,html,css,yml,yaml}files run throughdprint fmt - staged
package.jsonfiles run throughsort-package-json
If a commit changes formatting unexpectedly, review the staged diff and commit the formatted result.
- ESLint failure: run
pnpm lint:fix, then review and fix anything left manually. - dprint failure: run
pnpm format. - cspell failure: either fix the spelling or add the project-specific word to
cspell.jsonif it is intentional. - typecheck failure: fix the TypeScript error instead of weakening the config.
dprintis the source of truth for formatting.eslintis for code-quality issues that formatting does not cover.cspellshould stay clean; add game-specific vocabulary deliberately, not casually.pnpm checkshould stay green locally before opening a PR.