Skip to content

New Extension: Particle Engine#1724

Open
SharkPool-SP wants to merge 52 commits intoTurboWarp:masterfrom
SharkPool-SP:patch-43
Open

New Extension: Particle Engine#1724
SharkPool-SP wants to merge 52 commits intoTurboWarp:masterfrom
SharkPool-SP:patch-43

Conversation

@SharkPool-SP
Copy link
Collaborator

@SharkPool-SP SharkPool-SP commented Oct 15, 2024

Create Powerful Particle Engines with NO Clones

Screen.Recording.2024-10-15.at.12.31.42.AM.mov
wow.particles.mp4

@BludIsAnLemon
Copy link
Contributor

Peak!!

@Brackets-Coder
Copy link
Contributor

Two questions I have:

  1. Does high quality pen affect rendering quality?
  2. I've noticed that a lot of your extensions have gradient blocks. This looks cool, but the way you're implementing it with the patch is very weird. I think it'd be sick if we could use CSS colors and gradients as the color values for blocks instead of just hex values. How involved in the scratch-gui would it be to be able to do this?

@circledude64
Copy link

yes

@hammouda101010
Copy link

WOW! a new particle engine with no clones! that's great for performance and now overflow your projects with clones! (even if i use clones, a lot)

@SharkPool-SP
Copy link
Collaborator Author

Two questions I have:

  1. Does high quality pen affect rendering quality?

  2. I've noticed that a lot of your extensions have gradient blocks. This looks cool, but the way you're implementing it with the patch is very weird. I think it'd be sick if we could use CSS colors and gradients as the color values for blocks instead of just hex values. How involved in the scratch-gui would it be to be able to do this?

  1. no, this is not a "pen" canvas, to change quality, you'd need to use the set stage size block, but it comes at a cost of lower performance.

  2. The gui doesn't allow gradients in blocks at all. So I can't simply just put it in the extension block code. So I have to use the patch.

Additionally, blocks in the editor are all SVGs, which means you can't color them with any html property. You have do what I do and make SVG gradients or patterns.

@hammouda101010
Copy link

hammouda101010 commented Oct 15, 2024

Two questions I have:

  1. Does high quality pen affect rendering quality?
  2. I've noticed that a lot of your extensions have gradient blocks. This looks cool, but the way you're implementing it with the patch is very weird. I think it'd be sick if we could use CSS colors and gradients as the color values for blocks instead of just hex values. How involved in the scratch-gui would it be to be able to do this?

well, i just stole borrowed code for you to use the patch:

   function add2Body() {
    var svg = document.createElement("div");
    svg.innerHTML = \`<svg><defs>
      <linearGradient x1="100" y1="0" x2="100" y2="200" id="SPpartEngine-GRAD1" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0090ff"></stop><stop offset="50%" stop-color="#0000ff"></stop></linearGradient>
      </defs></svg>`;
    document.body.appendChild(svg);
  }
  if (Scratch.gui) Scratch.gui.getBlockly().then((SB) => {
    add2Body();
    if (!SB?.SPgradients?.patched) { // Gradient Patch by 0znzw & SharkPool
      SB.SPgradients = {gradientUrls: {}, patched: false};
      const BSP = SB.BlockSvg.prototype, BSPR = BSP.render;
      BSP.render = function(...args) {
        const res = BSPR.apply(this, args);
        let category;
        if (this?.svgPath_ && this?.category_ && (category = this.type.slice(0, this.type.indexOf("_"))) && SB.SPgradients.gradientUrls[category]) {
          const urls = SB.SPgradients.gradientUrls[category];
          if (urls) this.svgPath_.setAttribute("fill", urls[0]);
        }
        return res;
      }
      SB.SPgradients.patched = true;
    }
    SB.SPgradients.gradientUrls["SPpartEngine"] = ["url(#SPpartEngine-GRAD1)"];
  });

@Brackets-Coder
Copy link
Contributor

Two questions I have:

  1. Does high quality pen affect rendering quality?
  2. I've noticed that a lot of your extensions have gradient blocks. This looks cool, but the way you're implementing it with the patch is very weird. I think it'd be sick if we could use CSS colors and gradients as the color values for blocks instead of just hex values. How involved in the scratch-gui would it be to be able to do this?

well, i just stole borrowed code for you to use the patch:

function add2Body() { var svg = document.createElement("div"); svg.innerHTML = <svg><defs> <linearGradient x1="100" y1="0" x2="100" y2="200" id="SPpartEngine-GRAD1" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0090ff"></stop><stop offset="50%" stop-color="#0000ff"></stop></linearGradient> </defs></svg>; document.body.appendChild(svg); } if (Scratch.gui) Scratch.gui.getBlockly().then((SB) => { add2Body(); if (!SB?.SPgradients?.patched) { // Gradient Patch by 0znzw & SharkPool SB.SPgradients = {gradientUrls: {}, patched: false}; const BSP = SB.BlockSvg.prototype, BSPR = BSP.render; BSP.render = function(...args) { const res = BSPR.apply(this, args); let category; if (this?.svgPath_ && this?.category_ && (category = this.type.slice(0, this.type.indexOf(""))) && SB.SPgradients.gradientUrls[category]) { const urls = SB.SPgradients.gradientUrls[category]; if (urls) this.svgPath.setAttribute("fill", urls[0]); } return res; } SB.SPgradients.patched = true; } SB.SPgradients.gradientUrls["SPpartEngine"] = ["url(#SPpartEngine-GRAD1)"]; });

I've already looked at the code, but I don't intend to use it for my extensions. Thank you anyway though.

@Brackets-Coder
Copy link
Contributor

Brackets-Coder commented Oct 15, 2024

Two questions I have:

  1. Does high quality pen affect rendering quality?
  2. I've noticed that a lot of your extensions have gradient blocks. This looks cool, but the way you're implementing it with the patch is very weird. I think it'd be sick if we could use CSS colors and gradients as the color values for blocks instead of just hex values. How involved in the scratch-gui would it be to be able to do this?
  1. no, this is not a "pen" canvas, to change quality, you'd need to use the set stage size block, but it comes at a cost of lower performance.
  2. The gui doesn't allow gradients in blocks at all. So I can't simply just put it in the extension block code. So I have to use the patch.

Additionally, blocks in the editor are all SVGs, which means you can't color them with any html property. You have do what I do and make SVG gradients or patterns.

Interesting. I was just curious as to if we could change the scratch-gui repo to add some sort of functionality for gradients and CSS colors in the block color APIs, but I guess not - It didn't occur to me that the SVGs can't use CSS gradients. Maybe we could use this patch though, and manually inject the colors into the patch? IDK, it's just an idea. Probably won't be done though. What might be more possible is expanding the customizable block colors addon to allow for gradients.

@GarboMuffin GarboMuffin added the pr: new extension Pull requests that add a new extension label Oct 15, 2024
@SharkPool-SP
Copy link
Collaborator Author

Theres now an interpolation option! :)

hammouda101010

This comment was marked as abuse.

@CubesterYT
Copy link
Member

!format

@SharkPool-SP
Copy link
Collaborator Author

!format

@SharkPool-SP
Copy link
Collaborator Author

Rewritten in WebGL! This is now much faster and efficient :)

image

@SharkPool-SP
Copy link
Collaborator Author

the problem with that is it wont be interpolation per engine anymore. What youre suggesting is that all engines should have interpolation enabled when runtime turns it on?

It's complicated since there's two methods of toggle, one with the block and one without. Ideally both should "just work" intuitively but the two-way communication between both methods doesn't work "intuitively." To be honest I would just say keep either one and remove the other method, but if you can get both to work together that'd be better

okay I just removed the option to toggle interpolation, I just made it automatically turn on

@Brackets-Coder
Copy link
Contributor

okay I just removed the option to toggle interpolation, I just made it automatically turn on

Fantastic! If you're going to do it that way make sure you explain in the docs :D

@Brackets-Coder
Copy link
Contributor

I'll take a look later when I have time and probably approve

@SharkPool-SP
Copy link
Collaborator Author

I'll take a look later when I have time and probably approve

Already changed the docs

Copy link
Contributor

@Brackets-Coder Brackets-Coder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turning on interpolation and then creating an engine/emitter causes the emitter to be created without interpolation enabled.

Executing the "delete and wait" block still appears to disable interpolation on the emitter

Spamming the following block stack in the editor results in the There are too many active WebGL contexts on this page, the oldest context will be lost error.
Image

It seems to be mostly working and these are very nitpicky "polishing" issues but in general I approve of this PR

@SharkPool-SP
Copy link
Collaborator Author

@Brackets-Coder I fixed all those issues, the There are too many active WebGL contexts on this page, the oldest context will be lost bug I fixed in my previous commit, I used the same script in a forever loop, without refresh loop, and more... and couldnt get it

Copy link
Contributor

@Brackets-Coder Brackets-Coder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Interpolation before creating an emitter has been fixed

  • Delete and wait lacking interpolation has been fixed

  • The WebGL error still appears, I got it by spam-clicking the above stack in the running editor. The issue seems to be the following:

    const disposeEngine = (target) => {
        const engine = target[engineTag];
        if (!engine)
            return;
        vm.off("STAGE_SIZE_CHANGED", engine.drawable.stageSZChange);
        render.destroyDrawable(engine.drawableId, "sprite");
        render.destroySkin(engine.skinId);
        runtime.requestRedraw();

        engine.gl.deleteProgram(engine.programInfo.program);
        const glExtension = engine.gl.getExtension("WEBGL_lose_context");
        // >>>> here
        if (glExtension)
            glExtension.loseContext();
        engine.canvas.remove();
        target[engineTag] = undefined;
        allEngines.delete(target.getName());
    };

I'm getting the "Too many contexts, last context will be lost" error before I get a
"WebGL: INVALID_OPERATION: loseContext: context already lost"

It implies that loseContext isn't working because the browser automatically disposes of the context, which reveals a potential flaw with remove all. Maybe, if the argument is all, try simply deleting every existing WebGL context every time, so that when the block is spammed you'll never create too many?

I don't know. This seems like a non-trivial issue and something that could be looked further into. I don't know what's going on and since you can't replicate it on your machine, I don't know how to help you.

Image

I'm literally this 🤏 close to approval. You can probably show a video demonstrating how this issue is not reproducible, fix it really quick (which I doubt this is an easy-fix), or do something... But if you don't know what's going on and I don't know what's going on, I can either approve this right away or we can get another moderator to review and help us out

@SharkPool-SP
Copy link
Collaborator Author

Is that safari?

@Brackets-Coder
Copy link
Contributor

Brackets-Coder commented Jan 25, 2026

Is that safari?

Ah... That might be what's causing the issue. I'll test in Firefox and probably chrome too if I feel like it

@PPPDUD
Copy link
Member

PPPDUD commented Jan 25, 2026

@SharkPool-SP Are you sure that this shouldn't be a draft? It looks like you all still need a fair bit of work before merging.

Copy link
Contributor

@Brackets-Coder Brackets-Coder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the issue.

Working properly in Firefox, only returned WebGL context was lost. 93 times and no error.

I'm going to approve since the issue on Safari really only shows up in the console and doesn't seem to affect performance

@Brackets-Coder
Copy link
Contributor

Brackets-Coder commented Jan 25, 2026

Are you sure that this shouldn't be a draft? It looks like you all still need a fair bit of work before merging.

Based on what I've tested the most recent version is working as expected aside from the negligible issue above which only affects a small fraction of the population if they're looking in the console.

Any other issues I might've missed may be weeded out with a second review

Copy link
Member

@GarboMuffin GarboMuffin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Writing something. Hold on

@GarboMuffin
Copy link
Member

image

It's pixelated compared to the cat. I guess we never made this thing follow high quality pen?

If I want to make the particle engine work the same as high quality pen then what code am I expected to write?

The default transparency mode is also doing something wrong. The default particle colors are pink/purple/blue once they finish fading in, but while they're fading in, we see one here that is pure red. That doesn't make sense

Now zoom in on one of the particles. These particles are a solid purple but the edges are clearly pink. Not the same color. Probably related to the same transparency issue

image

There's also weird things going on with stacked transparent particles. These two particles overlapping should not form a deep red

image

@Brackets-Coder
Copy link
Contributor

I guess we never made this thing follow high quality pen?

@GarboMuffin see #1724 (comment)

@GarboMuffin
Copy link
Member

Here's a concrete example of a simple project using this extension

Untitled-48.zip (sb3 inside the zip)

What blocks will make the particles look good at any resolution?


Stopping project maybe should delete all the emitters. Currently if you use dynamic emitter names at all, if you want to stop seeing a screen full of particles your easiest way out is to manually run the delete engine block on whatever sprite. Which seems silly.


This throws an uncaught error

image

@PPPDUD
Copy link
Member

PPPDUD commented Jan 26, 2026

See what I mean?

@SharkPool-SP
Copy link
Collaborator Author

Is that safari?

Ah... That might be what's causing the issue. I'll test in Firefox and probably chrome too if I feel like it

Might be the cause, safari is garbage

@SharkPool-SP
Copy link
Collaborator Author

@SharkPool-SP Are you sure that this shouldn't be a draft? It looks like you all still need a fair bit of work before merging.

I mean not really anymore, at the time I pull requested it, it was ready. Now it's just minor changes

@SharkPool-SP
Copy link
Collaborator Author

!format

@SharkPool-SP
Copy link
Collaborator Author

Okay I fixed all the issues and more

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr: new extension Pull requests that add a new extension

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants