Adding a Patch
This page is generated from packages/reforged-types/AGENTS.md by docs:collect. Edit the source, not this page.
The Typings of each supported Patch, generated from the Patch files vendored under vendor/<Build>/ and the hand-curated Overlay under overlay/. Generated files (<Game version>/, <Game version>.d.ts, async-natives.json) are output: change them by curating the Overlay or the generator, then regenerating.
Run every command from the repository root. The root package.json is the private workspace package: typings:generate and typings:check are root scripts (pnpm typings:generate, pnpm typings:check), and the package's other scripts run as pnpm --filter reforged-types <script>.
New Patch loop
Follow these steps in order for a Patch update. The loop is done when the checks of step 6 pass and one commit holds the sources, the Overlay and the output.
- Vendor and generate. Pick the jass-history tag of the new Build (
Reforged-v<a.b.c.build>-...atgithub.com/Luashine/jass-history;pnpm patch-watch:plannames the newest live one) and runtypings:generate <tag>. It downloadscommon.j,blizzard.jandcommon.aiintovendor/<Build>/withprovenance.json, then regenerates every vendored Patch. Keep the previous Build vendored: the comparison in step 2 needs it. - Read the output. stdout lists, per pair of consecutive vendored Patches, the declarations only the newer one has (
In Patch <new> and not in Patch <old>), each assource:line: <Jass declaration>. The checklist follows. On any error it goes to stderr and the exit code is 1; with warnings only it goes to stdout after the summary line and the exit code is 0.no Overlay entry for <Jass declaration>; expected <path>: write the entry at that path.parameters do not match the Patch: the Patch renamed or reordered parameters; make the entry'sparamsmatch the Jass signature it prints (count, order, names).<file>:<line>: unknown line: the Patch uses grammar the parser rejects; extendsrc/parser.tswith a test intest/, never skip the line.- Warnings (
orphan Overlay entry): the entry matches no vendored Patch. See step 5.
- Curate. Write one JSON per missing entry at the printed path, shaped like its neighbours in the same folder (
functions/orglobals/). Apply the curation rules below to every entry. - Regenerate. Run
typings:generate(no tag) until it exits 0. Every error item of step 2 is gone; any remaining warning is accounted for in step 5. - Settle the Patch metadata.
- Set
reforged.patchinpackage.jsonand the supported Patch inREADME.mdto the new Build. Set the library'sreforged.patch(packages/reforged-ts/package.json) to it too, and any other field that must move;pnpm release:check-patcheschecks them all. The changeset's bumps and which fields move are indocs/release.md(Choosing the bump for a Patch). test/real-inputs.test.tsandtest/package.test.tspin the counts and facts of the supported Patch; update them to the new Build's measured values.- When the new Build shares its Game version with the old one (
3.0.0.24268then3.0.0.24277), the new Build generates the3.0.0/folder and the old one is only compared against. Delete the old Build'svendor/folder oncesinceis set; then delete the entries its removal leaves orphaned, since only the removed Natives had them.
- Set
- Check. Run
build,test(which includestypings:check) andverify; all three pass. - Commit
vendor/,overlay/, the generated output and the metadata of step 5 together, sotypings:checkpasses at every commit.
Curation rules
since: set it to the new Build on each function and global listed in step 2 as only in the newer Patch. Leave it off where the first Patch is uncertain; a type entry has nosince.returns.nullable: a handle-returning Native is nullable, except a converter (Convert*), an enum-like constant getter, and a Native the Nullability sweep (docs/research/nullability-sweep.md) saw return a handle in every case, whosenotescite the sweep's cases and Build. A Native the sweep saw return nothing is nullable whatever its family, itsnotesnaming the case. A string-returning Native follows its seeded family.params[].nullable:falseunless the Native is documented or observed to accept nil.async: trueonly for a Native whose value is valid for the local player alone (GetLocalPlayer);async-natives.jsonis generated from these flags.notesholds a fact from the project's research, rendered as@remarks; no jassdoc prose, which has no license.deprecatedholds the reason, rendered as@deprecated.- A per-parameter
typeoverride holds TypeScript type text.ConditionandFilteruse it (boolcode); add another only as a reviewed curation decision. origin: "war3-types-strict"marks a seeded entry; a new entry is hand-written and has noorigin.
Generator changes
Test through Seam 1 (generate() in src/generate.ts) with the fixture helpers in test/support/: small synthetic Patch and Overlay folders in, emitted text and diagnostics asserted. scripts/seed-from-war3-types-strict.ts is the one-off seed import, kept for provenance; the build type-checks it but never runs it.