feat: add era-based camp soundscapes

This commit is contained in:
2026-07-13 05:18:32 +09:00
parent 1eedd63163
commit b88a2d6ec2
21 changed files with 1347 additions and 14 deletions

View File

@@ -19,16 +19,17 @@ const server = await createServer({
});
try {
const { musicTracks, effectTracks } = await server.ssrLoadModule('/src/game/audio/audioAssets.ts');
const { musicTracks, ambienceTracks, effectTracks } = await server.ssrLoadModule('/src/game/audio/audioAssets.ts');
const scenarioModule = await server.ssrLoadModule('/src/game/data/scenario.ts');
const { battleScenarios } = await server.ssrLoadModule('/src/game/data/battles.ts');
const errors = [];
validateTrackMap(errors, 'music', musicTracks, 'bgm');
validateTrackMap(errors, 'ambience', ambienceTracks, 'ambience');
validateTrackMap(errors, 'effect', effectTracks, 'sfx');
validateAudioDirectoryCoverage(errors, musicTracks, effectTracks);
validateAudioDirectoryCoverage(errors, musicTracks, ambienceTracks, effectTracks);
validateStoryBgmReferences(errors, scenarioModule, battleScenarios, musicTracks);
validateLiteralAudioCalls(errors, musicTracks, effectTracks);
validateLiteralAudioCalls(errors, musicTracks, ambienceTracks, effectTracks);
if (errors.length) {
console.error(`Audio asset data verification failed with ${errors.length} issue(s):`);
@@ -39,7 +40,8 @@ try {
process.exitCode = 1;
} else {
console.log(
`Verified ${Object.keys(musicTracks).length} music tracks, ${Object.keys(effectTracks).length} effect tracks, ` +
`Verified ${Object.keys(musicTracks).length} music tracks, ${Object.keys(ambienceTracks).length} ambience tracks, ` +
`${Object.keys(effectTracks).length} effect tracks, ` +
`${collectStoryBgmReferences(scenarioModule, battleScenarios).length} story BGM references, and literal audio calls.`
);
}
@@ -64,8 +66,9 @@ function validateTrackMap(errors, label, tracks, expectedFolder) {
});
}
function validateAudioDirectoryCoverage(errors, musicTracks, effectTracks) {
function validateAudioDirectoryCoverage(errors, musicTracks, ambienceTracks, effectTracks) {
const registeredMusicPaths = new Set(Object.values(musicTracks).map(assetUrlToPath).filter(Boolean));
const registeredAmbiencePaths = new Set(Object.values(ambienceTracks).map(assetUrlToPath).filter(Boolean));
const registeredEffectPaths = new Set(Object.values(effectTracks).map(assetUrlToPath).filter(Boolean));
listAudioFiles(join(audioRoot, 'bgm')).forEach((path) => {
@@ -73,6 +76,11 @@ function validateAudioDirectoryCoverage(errors, musicTracks, effectTracks) {
errors.push(`BGM file "${path}" exists but is not registered in musicTracks`);
}
});
listAudioFiles(join(audioRoot, 'ambience')).forEach((path) => {
if (!registeredAmbiencePaths.has(path)) {
errors.push(`Ambience file "${path}" exists but is not registered in ambienceTracks`);
}
});
listAudioFiles(join(audioRoot, 'sfx')).forEach((path) => {
if (!registeredEffectPaths.has(path)) {
errors.push(`SFX file "${path}" exists but is not registered in effectTracks`);
@@ -89,8 +97,9 @@ function validateStoryBgmReferences(errors, scenarioModule, battleScenarios, mus
});
}
function validateLiteralAudioCalls(errors, musicTracks, effectTracks) {
function validateLiteralAudioCalls(errors, musicTracks, ambienceTracks, effectTracks) {
const musicKeys = new Set(Object.keys(musicTracks));
const ambienceKeys = new Set(Object.keys(ambienceTracks));
const effectKeys = new Set(Object.keys(effectTracks));
sourceFilesToScan.forEach((path) => {
@@ -100,6 +109,11 @@ function validateLiteralAudioCalls(errors, musicTracks, effectTracks) {
errors.push(`${path}:${lineForIndex(source, index)}: playMusic references unknown track "${key}"`);
}
});
collectLiteralCallKeys(source, 'playAmbience').forEach(({ key, index }) => {
if (!ambienceKeys.has(key)) {
errors.push(`${path}:${lineForIndex(source, index)}: playAmbience references unknown track "${key}"`);
}
});
collectLiteralCallKeys(source, 'playEffect').forEach(({ key, index }) => {
if (!effectKeys.has(key)) {
errors.push(`${path}:${lineForIndex(source, index)}: playEffect references unknown track "${key}"`);