Discuss Scratch

  • Discussion Forums
  • » Open Source Projects
  • » I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud? [RSS Feed]
Wowfunhappy
Scratcher
27 posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

Hello!

I use Scratch to introduce young children to programming. My beginner students often have issues with code like this:

when green flag clicked
forever
hide
show
end

or like this:

when green flag clicked
forever
move (10) steps
move (-10) steps
end

In normal Scratch, this code won't do anything, because Scratch only updates the screen at the end of a loop, or after a wait block. While this makes sense from an optimization perspective, it's very confusing for my students! It would be much clearer if Scratch always updated the screen immediately following a visual change.

This was really really bothering me, so I grabbed Scratch's code off of Github and changed it! I'm really happy with how this works, and I think it would help my students a great deal!

The only problem is, the open source “Scratch GUI” project on Github can only save and load projects locally. That's a nonstarter for my classes, where the children usually use a different Chromebook each week. I'm not a backend developer, so I'm a little concerned this will be the end of the road.

Is there any preexisting code for hooking up Scratch to a backend system? I'd want something as simple as possible—I'm not looking to scale up to a zillion users! I don't even necessarily need an account/login system (although that would definitely be ideal), just something where students can save a project with a unique name and retrieve it later.

Last edited by Wowfunhappy (Sept. 5, 2022 16:24:36)

ZZC12345
Scratcher
500+ posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

Unfortunately, Scratch's backend is not open source, so this will be hard to implement. If your change is not too big, you might want to try to implement it as a browser extension or something similar so it works with the Scratch backend in the Scratch editor. Just note that Scratch has a no-sharing-browser-extensions policy.
ZZC12345
Scratcher
500+ posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

After reading your code, I realized it would probably be hard to insert a hook into Scratch-VM. I did develop some backends (though I'm only 13, so not any good backends that are free of security bugs ), but overall, it's hard to create a backend that you can safely upload files and implement user control simply.

If you would like to make a backend:
I recommend Django, because I still don't like JavaScript (though es6 is getting better). You should implement the assets/project endpoints like this forum post indicates.

If you don't:
This is a much better option. Since you're using Google already, make a Google App, and save projects using Google Drive (auth docs). Easy and simple.
Wowfunhappy
Scratcher
27 posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

ZZC12345 wrote:

You should implement the assets/project endpoints like this forum post indicates.

Oh perfect, I can just do a POST request!

Thanks, I might actually just use a CloudFlare worker.

And yeah, not going for security here!

Last edited by Wowfunhappy (June 20, 2022 18:48:12)

ScratchcatandGobo
Scratcher
1000+ posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

you can with Scratch API, if your talking about stats.
Wowfunhappy
Scratcher
27 posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

Okay, nope, I am so completely confused!

I can see that `assetHost` and `projectHost` are set in `src/lib/project-fetcher-hoc.jsx`. But they're already set to the official Scratch website.

It's not clear to me what mechanism is telling scratch-gui “I am not a real instance of Scratch” and subsequently disabling cloud saving / account login / etc. I need to understand what's missing, so I can go through and possibly re-implement it.

Is any of this documented anywhere? Hopefully it doesn't live in scratch-www, that would likely be a nightmare. I don't need the entire website…

Last edited by Wowfunhappy (June 23, 2022 22:35:54)

Wowfunhappy
Scratcher
27 posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

I can get the save option to appear by setting `canSave` to `{true}` in `src/playground/render-gui.jsx`, but clicking the save button doesn't seem to do anything whatsoever, including show an error.

I set `projectHost` and `assetHost` to the URL of a Cloudflare worker I set up, but that worker isn't getting any hits whatsoever. This is also after I tested in Chromium with the `–disable-web-security` flag set to ensure there was no possibility of CORS or TLS restrictions getting in the way.
CST1229
Scratcher
1000+ posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

Wowfunhappy wrote:

It's not clear to me what mechanism is telling scratch-gui “I am not a real instance of Scratch” and subsequently disabling cloud saving / account login / etc. I need to understand what's missing, so I can go through and possibly re-implement it.
I think it's scratch-www telling scratch-gui the parameters to enable cloud saving.

Last edited by CST1229 (June 24, 2022 17:29:05)

ZZC12345
Scratcher
500+ posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

CST1229 wrote:

Wowfunhappy wrote:

It's not clear to me what mechanism is telling scratch-gui “I am not a real instance of Scratch” and subsequently disabling cloud saving / account login / etc. I need to understand what's missing, so I can go through and possibly re-implement it.
I think it's scratch-www telling scratch-gui the parameters to enable cloud saving.
I think the project saving logic may be in scratch-gui since it seems to be in project-saver-hoc. It seems that MenuBar should have an onClickSave prop but I can't find any trace of it in scratch-gui when searching. There seems to be a dispatch type “manualUpdateProject” but I can't find what that triggers either
ScratchcatandGobo
Scratcher
1000+ posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

OH!!! try using embed links. the code can be found here:
<iframe src="https://scratch-mit-edu.ezproxyberklee.flo.org/projects/652932390/embed“ allowtransparency=”true“ width=”485“ height=”402“ frameborder=”0“ scrolling=”no" allowfullscreen></iframe>
its in html

Last edited by ScratchcatandGobo (June 25, 2022 15:15:11)

Wowfunhappy
Scratcher
27 posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

I'm making progress!

I had to set canCreateNew to true in render-gui.jsx. Then my Cloudflare worker started getting hits.

When Scratch starts, it tries to save the new project to the backend server. If that fails, it won't attempt to use the backend at any point in the future…

ZZC12345
Scratcher
500+ posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

ScratchcatandGobo wrote:

OH!!! try using embed links. the code can be found here:
<iframe src="https://scratch-mit-edu.ezproxyberklee.flo.org/projects/652932390/embed“ allowtransparency=”true“ width=”485“ height=”402“ frameborder=”0“ scrolling=”no" allowfullscreen></iframe>
its in html
Sorry, but this topic is about discussing a fork of the Scratch editor, not html snippets for embedding Scratch. That snippet is a) for embedding the project player with scratch-www, and this is more about scratch-gui, and b) this is more jsx rather than html. Thanks for trying to help!

Wowfunhappy wrote:

I'm making progress!

I had to set canCreateNew to true in render-gui.jsx. Then my Cloudflare worker started getting hits.

When Scratch starts, it tries to save the new project to the backend server. If that fails, it won't attempt to use the backend at any point in the future…

Ah, interesting. So Scratch tries the create request first on the playground? If you want to try the GET request, maybe try localhost:port/#project-id-here to load a project, to see where the request ends up on your backend.

Last edited by ZZC12345 (July 1, 2022 07:21:19)

Wowfunhappy
Scratcher
27 posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

ZZC12345 wrote:

Ah, interesting. So Scratch tries the create request first on the playground? If you want to try the GET request, maybe try localhost:port/#project-id-here to load a project, to see where the request ends up on your backend.

Ah, yes, adding #project-id at the end of the URL sends the GET request! Thank you, I've been stuck at this point for several days!
hacktronics
Scratcher
100+ posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

Not sure, writing a scratch server backend, is a good idea. I don't like that design. I haven't look much at the server saving code, because creating a separate server would make my project uneconomical and I found scratch code not good enough for me.
Instead for https://ide.codeskool.cc/ , I rewrote the client itself to save it to firebase (not using any of the scratch saving & server logic), rather than implementing a separate server and figuring out the scratch communications. May be, if your problem is simple, then you don't need complex solutions. For me, saving to firebase directly from client, removes server and costly bills for me, while making the app even more fault tolerant to server crashes.
Again that my preference, as Scratch is too big, for them having there own servers makes sense, and every problem is different, I am just talking about my use case.

Last edited by hacktronics (Aug. 21, 2022 15:50:20)

Wowfunhappy
Scratcher
27 posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

For what it's worth, I did get this fully working. I'm using Scratch's saving/loading code alongside a Cloudflare worker to handle requests, and Google Firebase for storage. I had to use a bit of a hack to store the project title and username—I think this metadata is normally handled by scratch-www rather than scratch-gui—but other than that, my implementation is relatively clean.

For security reasons, I'm hesitant to post the code publicly. However, if anyone else needs a setup like this, please get in touch and I'll do my best to provide guidance!
ZZC12345
Scratcher
500+ posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

Wowfunhappy wrote:

For what it's worth, I did get this fully working. I'm using Scratch's saving/loading code alongside a Cloudflare worker to handle requests, and Google Firebase for storage. I had to use a bit of a hack to store the project title and username—I think this metadata is normally handled by scratch-www rather than scratch-gui—but other than that, my implementation is relatively clean.
Congratulations! I hope it's working smoothly!
Yes, you're right about the metadata. It's handled by the Scratch API (https://mv-ezproxy-com.ezproxyberklee.flo.org), not the Scratch Project Host (https://mv-ezproxy-com.ezproxyberklee.flo.org) or the Asset Host (https://mv-ezproxy-com.ezproxyberklee.flo.org). Usually, the title is stored in the filename when the project is saved to a computer, and since it's offline, there's no need for a username.
Hypothetically, if anything, posting it on GitHub won't be a security hazard as long as you don't post the IP or hostname.
Wowfunhappy
Scratcher
27 posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

I don't suppose anyone knows where the code is in Scratch to handle saving screenshots?

I'd thought I could do without screenshots, but—surprise!—It turns out first graders are quite bad at remembering to title their programs. Shocking, I know!

Screenshots would help them tell all the versions of “Untitled Project” apart from each other, if it's not too hard to do…

Last edited by Wowfunhappy (Oct. 19, 2022 15:15:15)

ZZC12345
Scratcher
500+ posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

Wowfunhappy wrote:

I don't suppose anyone knows where the code is in Scratch to handle saving screenshots?

I'd thought I could do without screenshots, but—surprise!—It turns out first graders are quite bad at remembering to title their programs. Shocking, I know!

Screenshots would help them tell all the versions of “Untitled Project” apart from each other, if it's not too hard to do…
For the stage, or for the workspace? For the stage, it's as simple as calling
Example
canvas.toDataURL();
// or
await canvas.toBlob();
but for the workspace, it gets harder, though you can look at the implementation of some of the screenshot parts of a specific browser extension I'm not allowed to name (try googling “scratch extension”).

As for where it is in Scratch, I found something in scratch-render:
LLK/scratch-render/src/RenderWebGL.js L2000
    /**
     * @param {snapshotCallback} callback Function called in the next frame with the snapshot data
     */
    requestSnapshot (callback) {
        this._snapshotCallbacks.push(callback);
    }
and this is used by getProjectThumbnail:
LLK/scratch-gui/src/lib/project-saver-hoc.jsx L280
        getProjectThumbnail (callback) {
            this.props.vm.postIOData('video', {forceTransparentPreview: true});
            this.props.vm.renderer.requestSnapshot(dataURI => {
                this.props.vm.postIOData('video', {forceTransparentPreview: false});
                callback(dataURI);
            });
            this.props.vm.renderer.draw();
        }
It seems to be handled by onUpdateProjectThumbnail in ProjectSaverHOC. Maybe try attaching a callback somewhere there?

Also, it would be great if this was open-sourced – I want to take a look at the finished code

Last edited by ZZC12345 (Oct. 20, 2022 06:03:38)

Wowfunhappy
Scratcher
27 posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

ZZC12345 wrote:

For the stage, or for the workspace? For the stage, it's as simple as calling
Example
canvas.toDataURL();
// or
await canvas.toBlob();

Thank you, I think that's all I need! (Just the stage is fine, goal is to have thumbnails like “My Stuff” in official Scratch.)

ZZC12345 wrote:

Also, it would be great if this was open-sourced – I want to take a look at the finished code

Unfortunately, I don't want to post all the code publicly for security reasons right now. While it's true there's no direct danger, I'm not a backend engineer, so I want to maintain some security-through-obscurity as an extra precaution. However, I absolutely don't want to hoard this either, and I'd be happy to answer questions and share specific code snippets if there's anything you're curious about. I can also share code with anyone who tracks me down and reaches out privately.

Last edited by Wowfunhappy (Oct. 22, 2022 20:52:20)

ZZC12345
Scratcher
500+ posts

I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?

Wowfunhappy wrote:

ZZC12345 wrote:

For the stage, or for the workspace? For the stage, it's as simple as calling
Example
canvas.toDataURL();
// or
await canvas.toBlob();

Thank you, I think that's all I need! (Just the stage is fine, goal is to have thumbnails like “My Stuff” in official Scratch.)
Great! If you care about implementing it “correctly”, you can also use the other methods I wrote about.

Wowfunhappy wrote:

ZZC12345 wrote:

Also, it would be great if this was open-sourced – I want to take a look at the finished code

Unfortunately, I don't want to post all the code publicly for security reasons right now. While it's true there's no direct danger, I'm not a backend engineer, so I want to maintain some security-through-obscurity as an extra precaution. However, I absolutely don't want to hoard this either, and I'd be happy to answer questions and share specific code snippets if there's anything you're curious about. I can also share code with anyone who tracks me down and reaches out privately.
That's fine, I was just curious. Good luck!
  • Discussion Forums
  • » Open Source Projects
  • » I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud? [RSS Feed]

Powered by DjangoBB