Skip to content

MiahNelah/lib-blockly

Repository files navigation

About

You love creating fantastic worlds and stories in Foundry, but you're afraid of macros? Would you rather plan your campaign than lear how to program?

LibBlockly offers a visual macro editor integrated with Foundry using Google Blockly technology. This type of editor is generally used for the initiation to programming, so it is easy to access: only the understanding of the algorithmic logic is necessary.

LibBlockly is also extensible framework which allow developers to create new blocks for general purposes or to help people to use their own modules.

Minimum Core Version: 0.9.245

Tutorials

You can find first steps guides here : English Français

Demo

How to create new Blockly Macro : new_macro

Hello, World !

HelloWorld

Let's prepare a battle ! image

Drag&Drop support

drag&drop

(more to come 😊)

Roadmap

The current roadmap is here : https://github.com/MiahNelah/lib-blockly/projects/1

Extensibility

You can easily add new custom blocks using Google Blockly documentation and Blockly Developer Tools. To create a new custom block, create a new class on the following template, then register the new block with Block Manager.

First, we need to specify our own custom block definition:

// "message0", "colour", "tooltip" and "helpUrl" will be pulled from translation file for you.
// Because we often need to translate strings inside definition, we expose defnitions as function to grant access to game.i18n.localise() helper.
const blocksDefinition = function() {
    return {
        "Foundry.Utils.Wait": {            
            "args0": [
                {
                    "type": "field_number",
                    "name": "delay",
                    "value": 1,
                    "min": 0
                },
                {
                    "type": "field_dropdown",
                    "name": "units",
                    "options": [
                        [game.i18n.localize("LibBlockly.Blocks.Foundry.Utils.Wait.Seconds"), "s"],
                        [game.i18n.localize("LibBlockly.Blocks.Foundry.Utils.Wait.Milliseconds"), "ms"]
                    ]
                }
            ],
            "previousStatement": null,
            "nextStatement": null,
        }
    }
}

Then, we need to add required translations. "Title", "Tooltip", "HelpUrl" and "Colour" are required. If you want to custimise "LibBlockly.Blocks" prefix, please have a look at CustomBlock constructor's parameters.

{
  "LibBlockly.Blocks.Foundry.Utils.Wait.Title": "Wait %1 %2",
  "LibBlockly.Blocks.Foundry.Utils.Wait.Tooltip": "",
  "LibBlockly.Blocks.Foundry.Utils.Wait.HelpUrl": "",
  "LibBlockly.Blocks.Foundry.Utils.Wait.Colour": "230",
}

We finally define a custom class to handle code generation:

class WaitCustomBlock extends CustomBlock {
    constructor() {
        super("Wait", "Foundry.Utils");
    }
  
    // The generateCode() describe how code is generated for your new block.
    // Use Blockly Developer Tools to get parameter resolution statements.
    generateCode(block) {
        const number_delay = block.getFieldValue('delay');
        const dropdown_units = block.getFieldValue('units');

        // In this specific block, we dynamically define a helper method to handle setTimeout promise.
        // This method will only be generated once if needed, and won't be if block is never used.
        // Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ is a placeholder to reference method hersel (useful for recursive calls).
        const delayHelper = Blockly.JavaScript.provideFunction_("blockly_delay_helper", [
            `function ${Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_}(delay) {`,
            `  return new Promise(resolve => {`,
            `    setTimeout(() => resolve(2), delay);`,
            `  });`,
            `}`
        ]);

        return `await ${delayHelper}(${dropdown_units === "s" ? number_delay * 1000 : number_delay});\n`;
    }
}

Let's stick all together !

Hooks.once("ready", () => {
    libBlockly.registerDefinitions(blocksDefinition());    

    libBlockly.registerBlockTypes([
        new WaitCustomBlock()
    ]);
 })

About

An integration of Google Blockly into Foundry VirtualTop.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Languages