Improve sixty-sixth battle map detail

This commit is contained in:
2026-07-10 03:32:31 +09:00
parent c86c8c9a93
commit 07cbfba5e6
13 changed files with 251 additions and 10 deletions

View File

@@ -21,7 +21,8 @@ try {
const { storyBackgroundAssets, storyBackgroundKeysFor } = await server.ssrLoadModule('/src/game/data/storyAssets.ts');
const scenarioModule = await server.ssrLoadModule('/src/game/data/scenario.ts');
const battleRows = collectBattleRows(battleScenarios, battleMapAssets);
const reviewedBattleMapPrefixes = collectReviewedBattleMapPrefixes();
const battleRows = collectBattleRows(battleScenarios, battleMapAssets, reviewedBattleMapPrefixes);
const storyUsage = collectStoryUsage(scenarioModule, storyBackgroundAssets, storyBackgroundKeysFor);
const storyRows = collectStoryRows(storyBackgroundAssets, storyUsage);
const report = renderReport({ battleRows, storyRows, storyUsage });
@@ -32,7 +33,7 @@ try {
await server.close();
}
function collectBattleRows(battleScenarios, battleMapAssets) {
function collectBattleRows(battleScenarios, battleMapAssets, reviewedBattleMapPrefixes) {
return Object.values(battleScenarios)
.map((scenario) => {
const assetUrl = battleMapAssets[scenario.mapTextureKey];
@@ -61,6 +62,7 @@ function collectBattleRows(battleScenarios, battleMapAssets) {
pxPerTile,
aspectDelta,
concerns: concerns.map((concern) => concern.label),
hasMapRepaintReport: reviewedBattleMapPrefixes.has(battleOrdinalPrefix(scenario.id)),
score
};
})
@@ -100,6 +102,22 @@ function battleOrder(left, right) {
);
}
function collectReviewedBattleMapPrefixes() {
try {
return new Set(
readdirSync('docs')
.map((fileName) => fileName.match(/^visual-asset-(.+)-map-repaint-v\d+-report\.md$/)?.[1])
.filter(Boolean)
);
} catch {
return new Set();
}
}
function battleOrdinalPrefix(battleId) {
return battleId.match(/^(.+)-battle-/)?.[1] ?? battleId;
}
function collectStoryUsage(scenarioModule, storyBackgroundAssets, storyBackgroundKeysFor) {
const usageByPath = new Map();
const pageReferences = [];
@@ -210,13 +228,17 @@ function storyOrder(left, right) {
function renderReport({ battleRows, storyRows, storyUsage }) {
const flaggedBattleRows = battleRows.filter((row) => row.concerns.length > 0);
const reviewedBattleRows = flaggedBattleRows.filter((row) => row.hasMapRepaintReport);
const pendingBattleRows = flaggedBattleRows.filter((row) => !row.hasMapRepaintReport);
const flaggedStoryRows = storyRows.filter((row) => row.concerns.length > 0);
const topBattleRows = flaggedBattleRows.slice(0, 12);
const topBattleRows = pendingBattleRows.slice(0, 12);
const topStoryRows = flaggedStoryRows.slice(0, 12);
const nextBattle = topBattleRows[0];
const nextStory = topStoryRows[0];
const battlePxPerTileValues = battleRows.map((row) => row.pxPerTile);
const storyPageReferenceCount = storyUsage.pageReferences.length;
const battleConcernText = (row) =>
[...row.concerns, row.hasMapRepaintReport ? 'repaint report exists' : undefined].filter(Boolean).join('<br>') || 'none';
return `${[
'# Visual Asset Quality Audit',
@@ -228,6 +250,7 @@ function renderReport({ battleRows, storyRows, storyUsage }) {
`- Target desktop viewport: ${targetViewport.width}x${targetViewport.height}`,
`- Battle map assets: ${battleRows.length}`,
`- Flagged battle map review rows: ${flaggedBattleRows.length}`,
`- Flagged battle map rows with repaint reports: ${reviewedBattleRows.length}`,
`- Battle map source pixel density range: ${formatNumber(Math.min(...battlePxPerTileValues))}-${formatNumber(Math.max(...battlePxPerTileValues))} px/tile`,
`- Story source backgrounds: ${storyRows.length}`,
`- Story page background references: ${storyPageReferenceCount}`,
@@ -237,6 +260,7 @@ function renderReport({ battleRows, storyRows, storyUsage }) {
'',
'- Existing verification already gates missing files and minimum dimensions; this audit ranks visual-review risk instead of failing the build.',
'- Battle maps are scored by source pixels per scenario tile, source/image aspect match, and WebP byte density.',
'- Battle maps with repaint reports stay in the inventory, but are skipped for the next-batch recommendation.',
'- Story backgrounds are scored by standard 1672x941 dimensions, repeat usage, and PNG byte density.',
'- The audit cannot judge composition or painterly quality by itself; top rows are candidates for desktop browser screenshot review.',
'',
@@ -254,7 +278,7 @@ function renderReport({ battleRows, storyRows, storyUsage }) {
'| ---: | --- | --- | ---: | ---: | ---: | ---: | --- |',
...topBattleRows.map(
(row) =>
`| ${row.score} | \`${row.id}\` | \`${row.mapKey}\` | ${row.mapColumns}x${row.mapRows} | ${row.width}x${row.height} | ${formatNumber(row.pxPerTile)} | ${formatNumber(row.bytesPerPixel, 4)} | ${row.concerns.join('<br>')} |`
`| ${row.score} | \`${row.id}\` | \`${row.mapKey}\` | ${row.mapColumns}x${row.mapRows} | ${row.width}x${row.height} | ${formatNumber(row.pxPerTile)} | ${formatNumber(row.bytesPerPixel, 4)} | ${battleConcernText(row)} |`
),
'',
'## Top Story Background Review Queue',
@@ -275,7 +299,7 @@ function renderReport({ battleRows, storyRows, storyUsage }) {
.sort((left, right) => left.id.localeCompare(right.id))
.map(
(row) =>
`| \`${row.id}\` | \`${row.mapKey}\` | ${row.mapColumns}x${row.mapRows} | ${row.width}x${row.height} | ${formatNumber(row.pxPerTile)} | ${formatNumber(row.bytes / 1024 / 1024, 2)} | ${row.concerns.join('<br>') || 'none'} |`
`| \`${row.id}\` | \`${row.mapKey}\` | ${row.mapColumns}x${row.mapRows} | ${row.width}x${row.height} | ${formatNumber(row.pxPerTile)} | ${formatNumber(row.bytes / 1024 / 1024, 2)} | ${battleConcernText(row)} |`
),
'',
'## Story Background Inventory',