Crackle SDK - Devlog

Hello! This is the development log for a modding SDK that I’m working on - called Crackle.
CrackleLogo
Yes. I named it Crackle because snap, crackle, pop. You think of a better name for it!
This SDK will allow users to create their own mods more easily.

Here I will take recommendations, and ask questions on what you, the community, thinks would work best! You too can also ask questions on how it will work.

That being said, here’s my first question for you guys: How should the Crackle logo be colored?

The Crackle logo’s colors would be cool as Cyan and Amber :slightly_smiling_face:

Pretty good logo! Better than whatever I’d do. I was actually planning to make a modding system, call it Snap!Mods, even started working on it. Better give that up! I agree with making it blue and yellow, for the Snap! logo of course. I think the line (for the c) and the mini lambda logo should be the blue, and the rest yellow. Maybe the other way around to make it EVEN similar to the Snap! logo. Anyway that’s enough logo talk. Make I could help? I would make it a browser extension kinda like Scratch Addons (that’s actually how I wanted to make Snap!Mods). Maybe use a seperate button, using Morphic’s SymbolMorph’s “cross” icon (that’s how I did it in Snap!Mods! I should probably shut up about that now). Heres a little planning from me:

  • Extension loads up, waits for Snap! to be loaded (probably waiting for a “world” variable (a WorldMorph) and one child in it, which is what Snap! creates. Then wait a bit after to make sure its loaded.
  • Do a little patching on the IDE to add the mod button
  • Create a global variable, e.g. “__crackle__”, using “window.__crackle__ = {…}” (maybe you can omit the “window.” part, I had to do that in Snap!Mods as I used a main function
  • And then, add mods and such to that

For the mods themselves, I think they should simply be a return statement, with a object containing the mod info and functions. And then, you should be able to refer to “this”; not as the object you returned (although it would copy some stuff from that) as a Mod object, which contains a “api” variable, containing the Crackle API. That could define a function to create a menu (in the mod button menu), a function to register a cleanup function, another to register events, and so on and so on. I’m actually going to share a couple snippets of code from my Snap!Mods project that might help:

Function (use with ‘await’) to wait for Snap! to be ready
function waitForSnapReady() {
    return new Promise(resolve => {
        const check = setInterval(() => {
            if (typeof world !== "undefined" && world.children.length > 0) {
                clearInterval(check);
                resolve();
            }
        }, 100);
    });
}
Code I used to add the mod button (you can tweak it with your menu options)
function adjustLabel() {
    controlBar.label.setPosition(
        new Point(
            controlBar.label.left() + BUTTON_OFFSET + modButton.width(),
            controlBar.label.top()
        )
    );
    controlBar.label.children[0].setPosition(controlBar.label.position());
}

// create mod button
const settingsButtonIndex = controlBar.children.findIndex(
    child => child instanceof PushButtonMorph && child.action === "settingsMenu"
);

const modButton = controlBar.children[settingsButtonIndex].fullCopy();
controlBar.addChild(modButton);

Object.assign(modButton, {
    about() {
        new DialogBoxMorph().inform(
            "About Snap!Mods",
            `Snap!Mods, a modding framework for Snap!\n` +
            `Developed by codingisfun2831\n` +
            `Version ${window._snap_mods_.version}`,
            world
        );
    },
    loadMod() {
        new DialogBoxMorph(
            this,
            (input) => {
                try {
                    window._snap_mods_.loadMod(input);
                    ide.showMessage(`Mod $loaded successfully!`);
                } catch (e) {
                    ide.showMessage(`Failed to load mod:\n${e}. Check the console for more details.`);
                    console.error(e);
                }
            },
            this
        ).promptCode(
            "Load mod from code",
            "// Paste your mod code here",
            world
        );
    },
    loadModFile() {
        const input = document.createElement("input");
        input.type = "file";
        input.accept = ".js,text/javascript,application/javascript";
        input.onchange = (e) => {
            const file = e.target.files[0];
            if (!file) return;
            const reader = new FileReader();
            reader.onload = (e) => {
                try {
                    let mod = window._snap_mods_.loadMod(e.target.result);
                    ide.showMessage(`Mod "${mod.name}" loaded successfully!`);
                } catch (e) {
                    ide.showMessage(`Failed to load mod:\n${e}`);
                }
            };
            reader.readAsText(file);
        };
        input.click();
    },

    manageMods: manageLoadedMods,

    action() {
        const menu = new MenuMorph(modButton);
        menu.addItem("About Snap!Mods...", "about");
        menu.addLine();
        menu.addItem("Load mod from code...", "loadMod");
        menu.addItem("Load mod from file...", "loadModFile");
        menu.addItem("Manage loaded mods...", "manageMods");

        let menus = {};

        for (let mod of window.snap_mods.loadedMods) {
            if (mod.doMenu) {
                menus[mod.name] = mod.menu;
            }
        }

        if (Object.keys(menus).length > 0) {
            menu.addLine();

            for (let [title, modMenu] of Object.entries(menus)) {
                menu.addMenu(title, modMenu);
            }

        }

        menu.popup(world, modButton.bottomLeft());
    }
});

modButton.children[0].name = "cross";

modButton.setPosition(new Point(
    controlBar.children[settingsButtonIndex].right() + BUTTON_OFFSET,
    controlBar.children[settingsButtonIndex].top()
));

adjustLabel();

// label updates
const originalUpdateLabel = controlBar.updateLabel;
controlBar.updateLabel = function() {
    originalUpdateLabel.call(this);
    adjustLabel();
};

Here’s the GitHub repo I made for it before giving up on it, also.

I would recommend making the project on Github. Also, learn git before instead of just uploading files to GitHub. Hope I can help with it!

honestly, I’m not sure about the color, but I think it would make more sense for the lambda to be combined with one of the letters.

You should definitely collaborate with me, or at least contribute to the mod. :slight_smile:
If you’ve ever heard of Geode, an SDK for Geometry Dash, it has a mod manager menu - I’m planning to make an online list for people to upload their own mods, similar to Geode’s.

I’m also planning on making the mod a simple browser extension, where you simply install and get access to all the mods people have made.

Thank you for the response!

So I think how we should store the mods online is using, well, a GitHub repo. If you’ve ever done any Windows modding, you probably know of Windhawk, a tool to create your own mods and use other peoples mods. How that works is a Github repo, with a mods folder or such, where people upload the mods. The Crackle browser extention simply uses the GIthub API to get all the files in that directory, and extract the info (e.g. id, name, description) and display that to the user.

Have you created a Github repo for the project yet? We should probably start with making the SDK and sticking to loading local files first, before making the mod repo or uploading the extention to any store.

P.S. Gelatin’s steakhouse is a good place. (referencing your profile location!)

Maybe even, once this SDK reaches a good state, make a mod file using it for your Personal Libraries mod!

Oh yeah! I use geode :slight_smile:

Have you created the repo or done any work on it yet?

Note: I’m guessing this is your Github account? I’m guessing that because I do see two Geometry Dash repos on there and you seem to know about Geometry Dash. If so, I do advise you to add that to your profile that you are on there. Either way, I don’t see the repo there. Create it!!

In fact, since I know how to make it I’ll probably code it and when you make the GitHub repo (with no content in it) I can push my copy to it so we can both work on it. I’m going to make it now.

UPDATE: I have finished the first version of Crackle on my own machine, waiting for Github repo to be created.

Also, make sure to add me as a contributer (im @ilikecoding-197 on GItHub) to the repo so I can push! You can search up how to if you don’t know, I’m too lazy to write a tutorial here.

Question @tethrarxitet could I help? I already have some ideas and I could help code it… if you let me help I’ll work on a base template

I’ve kind of already done that.

I believe so, if my account has the repo “Geometry-Dash-Revectorized”, then that’s me.
Also, I have created the repo, but I forgot to make it public. :expressionless:

Ooh, can’t wait to see it!

of course, it’s a contribution/collaboration type project! :slight_smile:
I might make an account named CrackleTeam for this - both for GitHub and the forums.

Im in school right now but just to make sure while it looks like you are still on the forums, is the Github created and public on your GitHub account? Did you also add me as a contributer??? That “CrackleTeam” is smart, probably when Crackle reaches a good state (I think you can transfer the owner of a repo). That Github account can also store the mods repo!

I’m in school right now too. :sweat_smile: Yes, the GitHub repo is created, but I haven’t published it, and no, I haven’t added you yet.

I will add you as a contributor when I get home.

Got it! When I get home I will also push my local repo to the GitHub so it will offically be public!

You’ve already mentioned that:

Leave it up to me to forget what I wrote and not bother to reread it.

PS. Just created @crackleteam. Currently waiting for the first reply to be approved. :slight_smile:

By reply, you mean like a reply on this topic? If so, I can’t wait to see it!

For GitHub, I’m pretty sure you can create a organization for free instead of a normal GitHub account. Funny that I just got a warning from the forums telling me that I’m postin too much on this topic. I mean there’s no one else to say anything, I might as well keep it going. Maybe I should stop posting until I get home. I will no longer be on until like 3:10pm or something