Discuss Scratch

8to16
Scratcher
1000+ posts

Custom turbowarp blocks won't work

i tried adding blocks like these to turbowarp:
all at once {
}::control

<clone?::control>

when @stopSign clicked::events hat

open url [https://unnamedmod.test]::sensing
however, when adding blocks and trying to run them, i get an error.

(side note: “all at once” doesn't give an error, but the code in it runs normally as if this was vanilla scratch.)

how do i fix this? i tried adding these lines to src/compiler/compat-blocks.js, but no luck
    'event_whenstopclicked',
    'sensing_openurl'
o97doge
Scratcher
500+ posts

Custom turbowarp blocks won't work

I believe there are two different types of blocks that the compiler checks to generate JavaScript (or in this case, run the block in the interpreter), stacked blocks, and input blocks (what I assume to be reporters and booleans.)

Have you tried putting it in the respective spots? Unfortunately, I can't help any further, because this is not what I do. Because in 99.9% of cases, you're looking to generate JavaScript. I can help you with that.

Legal disclaimer (Due to code being a commented version of code from LibreKitten-vm):
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.

This program is based on [scratchfoundation/scratch-vm](https://github.com/scratchfoundation/scratch-vm), which is under this license:

```
Copyright (c) 2016, Massachusetts Institute of Technology
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
```

For example, if you wanted to add:
change x by: (15) y by: (15) :: motion
You would first need to add a block entry to src/compiler/irgen.js (I'm assuming you already know how to add a block to the GUI and block library.)

Put in the descendStackedBlock function:
        // Block ID
        case 'motion_changexyby':
            return {
                // "kind" is code generator ID.
                kind: 'motion.changeXY',
                dx: this.descendInputOfBlock(block, 'DX'), // Added X input.
                dy: this.descendInputOfBlock(block, 'DY') // Added Y input.
            };
This tells the compiler how to pass the input from the user to the code generator function.

Now, here's the part where you generate JavaScript. You need to add a code generator to src/compiler/jsgen.js.

Put in the descendStackedBlock function:
        // Check for this block's code generator ID.
        case 'motion.changeXY':
            // Add code to generated JavaScript.
            this.source += `target.setXY(target.x + ${this.descendInput(node.dx).asNumber() /* Insert added X input. */ }, target.y + ${this.descendInput(node.dy).asNumber() /* Insert added Y input. */ });\n`;
            break;
Test it, and then you're done!

Last edited by o97doge (Jan. 11, 2025 22:24:17)

8to16
Scratcher
1000+ posts

Custom turbowarp blocks won't work

o97doge wrote:

I believe there are two different types of blocks that the compiler checks to generate JavaScript (or in this case, run the block in the interpreter), stacked blocks, and input blocks (what I assume to be reporters and booleans.)

Have you tried putting it in the respective spots? Unfortunately, I can't help any further, because this is not what I do. Because in 99.9% of cases, you're looking to generate JavaScript. I can help you with that.

yada yada yada edit src/compiler/irgen.js and then src/compiler/jsgen.js and then you're done
ok, but what about hat blocks?
here is my modded scratch-vm code
    /**
     * Start all threads that start with the green flag.
     */
    greenFlag () {
        // Emit stop event to allow blocks to clean up any state.
        this.emit(Runtime.PROJECT_STOP_ALL);
        // Dispose all clones.
        const newTargets = [];
        for (let i = 0; i < this.targets.length; i++) {
            this.targets[i].onStopAll();
            if (Object.prototype.hasOwnProperty.call(this.targets[i], 'isOriginal') &&
                !this.targets[i].isOriginal) {
                this.targets[i].dispose();
            } else {
                newTargets.push(this.targets[i]);
            }
        }
        this.targets = newTargets;
        // Dispose of the active thread.
        if (this.sequencer.activeThread !== null) {
            this._stopThread(this.sequencer.activeThread);
        }
        // Remove all remaining threads from executing in the next tick.
        this.threads = [];
        this.threadMap.clear();
        this.resetRunId();
        this.emit(Runtime.PROJECT_START);
        this.updateCurrentMSecs();
        this.ioDevices.clock.resetProjectTimer();
        this.targets.forEach(target => target.clearEdgeActivatedValues());
        // Inform all targets of the green flag.
        for (let i = 0; i < this.targets.length; i++) {
            this.targets[i].onGreenFlag();
        }
        this.startHats('event_whenflagclicked');
    }
    /**
     * Stop "everything."
     */
    stopAll () {
    
        // Emit stop event to allow blocks to clean up any state.
        this.emit(Runtime.PROJECT_STOP_ALL);
        // Dispose all clones.
        const newTargets = [];
        for (let i = 0; i < this.targets.length; i++) {
            this.targets[i].onStopAll();
            if (Object.prototype.hasOwnProperty.call(this.targets[i], 'isOriginal') &&
                !this.targets[i].isOriginal) {
                this.targets[i].dispose();
            } else {
                newTargets.push(this.targets[i]);
            }
        }
        this.targets = newTargets;
        // Dispose of the active thread.
        if (this.sequencer.activeThread !== null) {
            this._stopThread(this.sequencer.activeThread);
        }
        this.startHats('event_whenstopclicked');
    }
o97doge
Scratcher
500+ posts

Custom turbowarp blocks won't work

8to16 wrote:

(#3)
-snip-
ok, but what about hat blocks?
-snip-
Last time I tried adding one, I think it was the same as vanilla Scratch. So you can follow this guide: https://mrcomputer1.github.io/scratch-modding/3.0/tutorial/adding-hat-blocks
8to16
Scratcher
1000+ posts

Custom turbowarp blocks won't work

o97doge wrote:

8to16 wrote:

(#3)
-snip-
ok, but what about hat blocks?
-snip-
Last time I tried adding one, I think it was the same as vanilla Scratch. So you can follow this guide: https://mrcomputer1.github.io/scratch-modding/3.0/tutorial/adding-hat-blocks
please view my code.
i implemented the stop sign clicked block, but nothing really happened
also how do you implement a warp block? my attempt
// irgen
        case 'control_all_at_once':
            // In Scratch 3, this block behaves like "if 1 = 1"
            return {
                kind: 'control.allAtOnce',
                condition: {
                    kind: 'constant',
                    value: true
                },
                whenTrue: this.descendSubstack(block, 'SUBSTACK'),
                whenFalse: []
            };
// jsgen
        case 'control.allAtOnce':
            this.isWarp = false;
            this.descendStack(node.do, new Frame(false));
            this.isWarp = true;
            break;
acts like vanilla
do i have to use the source += thing? or swap false and true?

Last edited by 8to16 (Jan. 11, 2025 23:39:33)

AmpElectrecuted
Scratcher
500+ posts

Custom turbowarp blocks won't work

bump

8to16 wrote:

please view my code.
i implemented the stop sign clicked block, but nothing really happened
also how do you implement a warp block? my attempt
// irgen
        case 'control_all_at_once':
            // In Scratch 3, this block behaves like "if 1 = 1"
            return {
                kind: 'control.allAtOnce',
                condition: {
                    kind: 'constant',
                    value: true
                },
                whenTrue: this.descendSubstack(block, 'SUBSTACK'),
                whenFalse: []
            };
// jsgen
        case 'control.allAtOnce':
            this.isWarp = false;
            this.descendStack(node.do, new Frame(false));
            this.isWarp = true;
            break;
acts like vanilla
do i have to use the source += thing? or swap false and true?
o97doge
Scratcher
500+ posts

Custom turbowarp blocks won't work

8to16 wrote:

(#5)
-snip-
please view my code.
i implemented the stop sign clicked block, but nothing really happened
-snip-
This is where I'm stuck. So it is easier for me to debug and view your code, you need to release your VM code somewhere like GitHub.
Edit: Actually, just show me your src/blocks/scratch3_event.js file.

Last edited by o97doge (Jan. 29, 2025 20:56:32)

BigNate469
Scratcher
1000+ posts

Custom turbowarp blocks won't work

I seem to recall another thread several months ago about the all at once block (although I can't find it), try swapping true and false.

Last edited by BigNate469 (Jan. 29, 2025 21:01:15)

paster_master100
Scratcher
75 posts

Custom turbowarp blocks won't work

8to16 wrote:

i tried adding blocks like these to turbowarp:
all at once {
}::control

<clone?::control>

when @stopSign clicked::events hat

open url [https://unnamedmod.test]::sensing
however, when adding blocks and trying to run them, i get an error.

(side note: “all at once” doesn't give an error, but the code in it runs normally as if this was vanilla scratch.)

how do i fix this? i tried adding these lines to src/compiler/compat-blocks.js, but no luck
    'event_whenstopclicked',
    'sensing_openurl'
i believe that the last 3 blocks are actually in the scratch mod's extension section

Powered by DjangoBB