Hey guys!
I wrote a small Webpack hack to automatically load Tilesets into Tiled maps, and I think this could be useful for some of you, so I decided to share it here.
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { promises: fs } = require('fs');
const stageFiles = await fs.readdir(STAGES_PATH);
// get only the JSON files
const stageJsons = stageFiles
.filter((stage) => stage.split('.')[1] === 'json');
const copyWebpackPluginPatterns = [];
stageJsons.forEach((stage) => {
copyWebpackPluginPatterns.push({
from: `${STAGES_PATH}/${stage}`,
to: '../assets/stages',
transform: (fileBuffer, elPath) => {
const manifestString = fileBuffer.toString();
const stageData = JSON.parse(manifestString);
const newTilesets = stageData.tilesets.map((tileset) => {
// firstgid is an important id reference for Tiled
const { firstgid } = tileset;
if (!tileset.source) {
// if there's no source, it means the Tileset
// is already embeded
return tileset;
}
// on my setup, stages are in root/stages/
// and the tilesets are in root/tilesets/
// so we need to remove "../tilesets/" from the path
// and load it based on the root dir of the tilesets
const filePath = tileset.source.replace('../tilesets/', '');
// eslint-disable-next-line import/no-dynamic-require
const tilesetData = require(`${TILESETS_PATH}/${filePath}`);
if (!tilesetData) {
console.error('Could not find file', `${TILESETS_PATH}/${filePath}`);
return tileset;
}
return {
...tilesetData,
firstgid,
};
});
stageData.tilesets = newTilesets;
return Buffer.from(JSON.stringify(stageData));
},
});
});
module.exports = {
plugins: [
new CopyWebpackPlugin({
patterns: [
...copyWebpackPluginPatterns,
],
}),
],
};
I wrote a detailed explanation about why and how this was done here: https://pablo.gg/en/blog/games/loading-external-tileset-file-on-phaser-js-using-webpack-skate-platformer-game-devlog-7/