Skip to content

Asset Transform

Modify game assets during build.

WARNING

Only available in onModifyAssets hook.

Methods

replaceInFile(path, search, replace)

Replace text in a file:

javascript
gemshell.transform.replaceInFile(
  'index.html',
  '{{VERSION}}',
  context.config.version
);

appendToFile(path, content)

Append content to file:

javascript
gemshell.transform.appendToFile(
  'index.html',
  '<script>console.log("Build: " + Date.now())</script>'
);

prependToFile(path, content)

Prepend content to file:

javascript
gemshell.transform.prependToFile(
  'main.js',
  '// Built with GemShell\n'
);

injectIntoHtml(content, position)

Inject content into HTML:

javascript
// Inject into <head>
gemshell.transform.injectIntoHtml(
  '<meta name="version" content="1.0.0">',
  'head'
);

// Inject at end of <body>
gemshell.transform.injectIntoHtml(
  '<script src="analytics.js"></script>',
  'body-end'
);

// Inject at start of <body>
gemshell.transform.injectIntoHtml(
  '<div id="overlay"></div>',
  'body-start'
);

Example: Version Injection

javascript
module.exports = {
  name: 'Version Injector',
  version: '1.0.0',
  
  async onModifyAssets(context, settings) {
    const version = context.config.version;
    const buildTime = new Date().toISOString();
    
    // Replace placeholders
    gemshell.transform.replaceInFile('index.html', '{{VERSION}}', version);
    gemshell.transform.replaceInFile('index.html', '{{BUILD_TIME}}', buildTime);
    
    // Inject meta tag
    gemshell.transform.injectIntoHtml(
      `<meta name="game-version" content="${version}">`,
      'head'
    );
    
    gemshell.log(`Injected version ${version}`);
  }
};

Example: Add Watermark

javascript
module.exports = {
  name: 'Watermark',
  version: '1.0.0',
  
  settings: [
    { id: 'text', type: 'text', label: 'Watermark Text', default: 'DEMO' },
    { id: 'position', type: 'select', options: ['top-left', 'top-right', 'bottom-left', 'bottom-right'], default: 'bottom-right' }
  ],
  
  async onModifyAssets(context, settings) {
    const css = `
      .gs-watermark {
        position: fixed;
        ${settings.position.includes('top') ? 'top: 10px' : 'bottom: 10px'};
        ${settings.position.includes('left') ? 'left: 10px' : 'right: 10px'};
        padding: 4px 8px;
        background: rgba(0,0,0,0.5);
        color: white;
        font-family: sans-serif;
        font-size: 12px;
        z-index: 99999;
        pointer-events: none;
      }
    `;
    
    const html = `<div class="gs-watermark">${settings.text}</div>`;
    
    gemshell.transform.injectIntoHtml(`<style>${css}</style>`, 'head');
    gemshell.transform.injectIntoHtml(html, 'body-end');
    
    gemshell.log('Watermark added');
  }
};

Example: Minify JSON

javascript
module.exports = {
  name: 'JSON Minifier',
  version: '1.0.0',
  
  async onModifyAssets(context, settings) {
    const jsonFiles = gemshell.glob('**/*.json');
    let saved = 0;
    
    for (const file of jsonFiles) {
      const original = gemshell.fs.read(file);
      const data = JSON.parse(original);
      const minified = JSON.stringify(data);
      
      if (minified.length < original.length) {
        gemshell.fs.write(file, minified);
        saved += original.length - minified.length;
      }
    }
    
    gemshell.log(`Minified JSON, saved ${(saved / 1024).toFixed(1)} KB`);
  }
};