Skip to content

Instantly share code, notes, and snippets.

@nommiin
Last active December 11, 2022 22:53
Show Gist options
  • Select an option

  • Save nommiin/2858d3ba0a2cf3ef28d2b9828b22aa7d to your computer and use it in GitHub Desktop.

Select an option

Save nommiin/2858d3ba0a2cf3ef28d2b9828b22aa7d to your computer and use it in GitHub Desktop.
Write macros for GameMaker with JS!
/*
Setup:
1. Create a script named "__meta"
2. Add a line containing "#autogen" anywhere (also it needs to be a comment lol)
3. Create a folder named "tools" in your project root and copy this gist's contents into a file named "meta.js"
4. Create a "pre_project_step.bat" (1) or "pre_project_step.sh" (2) script in your project root and copy the below script:
(1)
@echo off
node %YYprojectDir%\tools\meta.js
(2)
#!/bin/bash
# set echo off
node "${YYprojectDir}/tools/meta.js"
4.5) !!! If you're using macOS (and maybe Ubuntu?), be sure to run GameMaker via Terminal so environment variables are passed along to scripts properly
5. Run your project, macros defined in the "generate" function should be written to "__meta"
*/
const fs = require("node:fs");
const path = require("node:path");
const proc = require("node:child_process");
/**
*
* @param {string} project The base directory of the project
* @param {string[]} content The pre-existing contents of the script
* @param {string} config The current configuration selected in the IDE
* @returns content with the newly generated macros
*/
function generate(project, content, config) {
const date = new Date(), macros = {
DEBUG: config === "debug",
VERSION: `"${date.getFullYear()}.${date.getMonth() + 1}.0"`,
BRANCH: `"${proc.execSync("git symbolic-ref --short HEAD", {cwd: project, encoding: "utf-8"}).trim()}"`
};
for(let i = 0; i < content.length; i++) {
const line = content[i];
if (line.indexOf("#autogen") > -1) {
let end = -1;
for(let j = i + 1; j < content.length; j++) {
const skip = content[j].trim();
if (skip.length === 0) continue;
if (skip.startsWith("#macro")) continue;
end = j;
break;
}
if (end === -1) {
console.log(`[WARNING] Could not find end of autogen defined macros, writing to end of file instead`);
end = content.length;
}
const amount = end - (i + 1), macro = Object.keys(macros).map(e => {
return `#macro ${e} ${macros[e]}`;
});
if (end > -1) macro.push("");
content.splice(i + 1, amount, macro.join("\n"));
break;
}
}
return content.join("\n");
}
try {
const yyp = process.env["YYprojectPath"];
if (!yyp) {
throw `Could not find "YYprojectPath" environment variable`;
}
const project = path.dirname(yyp);
(function(file) {
const script = path.normalize(path.join(project, file));
if (!fs.existsSync(script)) {
throw `Could not find script: ${script}`;
}
const content = fs.readFileSync(script, {encoding: "utf-8"}).split("\n");
fs.writeFileSync(script, generate(project, content, process.env["YYconfig"] ?? "Default"));
})(path.normalize("/scripts/__meta/__meta.gml"));
process.exit(0);
} catch (e) {
console.error(`An error in meta.js has occured:\n- ${e}`);
process.exit(1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment