Publish the smogon sets unstamped

xy/ and xyicons/ rsync into /smog2/sprites, and the dex composes those urls
itself, sprites/xy/charizard.gif, with no lookup in between. Manifest
content-stamps every copy and writes `name.ext` -> the stamped filename beside
it, which is worth something only to a reader that consults the manifest, and
nothing on the dex side does yet. A deploy of these two sets therefore lands a
tree the dex cannot read.

Copy under the published name with no stamp, and drop the manifests, which
have no second name left to record. The duplicate check survives the loss:
ActionQueue already refuses two copies to one path, so the collision
Manifest.copy used to throw on is an invalid queue instead, and the
published-name layering of the last commit is still what keeps xy/ clear of
it. 1650 files under xy/, 1533 under xyicons/.

assets/ keeps its Manifest and its stamps, since the smogdex reads those urls
out of __meta rather than composing them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Christopher Monsanto
2026-08-23 00:53:33 -04:00
parent 61df5387d2
commit f278ed4d73

View File

@@ -1,9 +1,9 @@
import {gen10Modelslike} from './rules/modelslike.ts';
import {Manifest, type Sprite, publishedNames, spritecopy} from './rules/publish.ts';
import {type Sprite, publishedNames} from './rules/publish.ts';
import {forEachRule} from './tools/build/artifact.ts';
import {compresspng, trimimg} from './tools/build/helpers.ts';
import {deploy} from './tools/deploy/api.ts';
import {type DeployCtx, deploy} from './tools/deploy/api.ts';
// xy/ animations: first source wins per sprite name.
@@ -32,41 +32,39 @@ let xyGen5 = forEachRule('src/sprites/gen5/*.png', [
deploy(async ctx => {
let seen = new Set<string>();
let manifest = new Manifest(ctx);
// First source wins per published name rather than per filename, because
// the later sources are backfills and a name can be spelled more than one
// way. gen 5 carries a sprite per forme slot, so its six Minior meteors
// and two Zygarde Power Construct slots all want the name the models
// already publish, which the manifest would reject as a duplicate.
let xycopy = async (f: Sprite) => {
// the later sources are backfills and one name can be spelled several
// ways. gen 5 carries a sprite per forme slot, so its six Minior meteors
// and its two Zygarde Power Construct slots all want the name the models
// already published, and two copies to one path is an invalid queue.
let xycopy = (f: Sprite) => {
let names = publishedNames(f);
if (names.some(n => seen.has(n))) {
return;
}
for (let name of names) {
seen.add(name);
await manifest.copy(f, {dir: 'xy'}, name);
}
smogonSpritecopy(ctx, f, 'xy', names);
};
for (let f of await ctx.list('src/models')) {
await xycopy(f);
xycopy(f);
}
for (let f of xyModels) {
await xycopy(f);
xycopy(f);
}
for (let f of xyChampions) {
await xycopy(f);
xycopy(f);
}
for (let f of await ctx.list('src/sprites/gen5')) {
if (f.ext === 'gif') {
await xycopy(f);
xycopy(f);
}
}
for (let f of xyGen5) {
await xycopy(f);
xycopy(f);
}
manifest.write('xy/manifest.json');
});
// xyicons/: trimmed gen6 minisprites.
@@ -76,14 +74,24 @@ let xyIcons = forEachRule('src/minisprites/pokemon/gen6/*.png', {
cmds: [trimimg(), compresspng({config: 'MINISPRITE'})],
}, '%b');
deploy(async ctx => {
let manifest = new Manifest(ctx);
deploy(ctx => {
for (let f of xyIcons) {
await spritecopy(manifest, f, {dir: 'xyicons'});
smogonSpritecopy(ctx, f, 'xyicons', publishedNames(f));
}
manifest.write('xyicons/manifest.json');
});
// The smogon side asks for a fixed path, /sprites/xy/charizard.gif, and reads
// no manifest yet, so these copies carry no content stamp and the published
// name is the whole filename.
function smogonSpritecopy(ctx: DeployCtx, f: Sprite, dir: string, names: string[]): void {
if (f.ext === null) {
throw new Error(`Sprite ${f.name} has no extension`);
}
for (let name of names) {
ctx.copy(f, `${dir}/${name}.${f.ext}`);
}
}
// Deprecated, unstamped sets. Reviving one also means importing what it
// uses (PNG_DETERMINISTIC, base, spriteglob, itemspritecopy) and giving the
// copies a Manifest, as the stamped deploys above do.