Discuss Scratch

pkhead
Scratcher
1000+ posts

wags - WebAssembly to GoboScript

https://codeberg.org/lonesound/wags

Wags is a tool which compiles WebAssembly modules into a goboscript source file; that is, into Scratch code. This will effectively allow you to write parts of Scratch project in languages such as C, C++, Rust, e.t.c.

This thread serves as the devlog for my insanity, whenever I feel like posting anything.

Frequently* Asked Questions:
Q: How will I run this?
A: This will be a command-line tool. You would type “wags path/to/module.wasm -o path/to/out.gs” into your terminal.

Q: What is WebAssembly?
A: WebAssembly is, from their website, a binary instruction format for a stack-based virtual machine. It is designed as a portable compilation target for programming languages (also from their website).

Q: Has anyone made anything similar before?
A: Yeah apparently someone made an LLVM backend but it's already too late for me. also i think it's unfinished.

Q: Why waste your time making this?
A: 1: It's cool. 2: I hate Scratch programming. 3: I wanted to see if I can port C to Scratch code, specifically to port Unyuland Advance without rewriting the entire game.

Q: Why not just fork a pre-existing “retargetable” C compiler, like TCC, LCC, or chibicc?
A: I wanted it to be able to support the full C11 (or higher) standard with GCC extensions. Support for other languages would be nice as well. Also I wanted to do this in the easiest way possible; WebAssembly is the easiest way possible.

Q: Why WebAssembly?
A: WebAssembly, in addition to having good support as a compilation target for languages such as C and Rust, is abstract enough to be able to map to Scratch code with relative ease: it cannot access code as memory, enforces structured control flow, and allows for an unbounded number of registers for intermediate storage, through function locals and the stack.

Q: Is this related to your previous project Nanolang?
A: This is completely unrelated to Nanolang, which aimed to create a new language based off C which compiled to goboscript. This iteration of my absolute refusal to actually code in Scratch now aims to “compile from C” directly.

Q: How will the compiled code work within the Scratch runtime?
A: Compiled code will always be placed into a custom block with no screen refresh. Functions with export names of the format "__wags_msghand_[name]“ will be compiled as being called inside a ”when I receive [name]" hat block. Within the command-line interface will be a method to insert raw goboscript code from a file into the output. This will allow the user to provide the definitions of unresolved function imports in raw Scratch code, which can be used to insert custom glue code or implement parts of the C standard library (e.g. the math library). This is very subject to change, however, but hopefully it will be enough to allow this tool to make any kind of Scratch project.

*nobody has ever asked these questions at the time of writing. i just made them up.

Last edited by pkhead (Yesterday 22:30:28)

pkhead
Scratcher
1000+ posts

wags - WebAssembly to GoboScript

right now all this tool can do is compile very very very basic WebAssembly modules. it supports i32, f32, and f64 types, basic arithmetic, comparisons, locals, and non-looping control flow with basic 1- or 2-level branching patterns that can easily compile into if and if-else. the if,then,and else instructions are not yet supported. the block/loop/br/br_if instructions are more important, since if,then,else are just behavioral subsets of those instructions.

next goal is to implement the ability to compile loops and branching patterns of arbitrary complexity, which I believe should be possible in Scratch, though obviously not “state”-less.
novice27b
Scratcher
1000+ posts

wags - WebAssembly to GoboScript

The name could maybe use a little workshopping…

WASM -> Scratch does make a lot of sense though. The main reason is, WASM has no “jump/goto” instruction - and neither does Scratch. Working around this is one of the big challenges with compiling other languages into Scratch, but compilers targeting WASM already solve it!

Last edited by novice27b (Aug. 17, 2026 23:16:48)

scratchcode1_2_3
Scratcher
1000+ posts

wags - WebAssembly to GoboScript

No…. please don't name it that…

But the tool looks cool….
pkhead
Scratcher
1000+ posts

wags - WebAssembly to GoboScript

scratchcode1_2_3 wrote:

No…. please don't name it that…

But the tool looks cool….
nooo ignore that definition.. and. its like. ScratchCAT. i conceived this whole clever design for a logo…
fine, maybe i ought to think of another name. i don't know what though. this is the only idea i had.
scratchcode1_2_3
Scratcher
1000+ posts

wags - WebAssembly to GoboScript

pkhead wrote:

(#5)

scratchcode1_2_3 wrote:

No…. please don't name it that…

But the tool looks cool….
nooo ignore that definition.. and. its like. ScratchCAT. i conceived this whole clever design for a logo…
fine, maybe i ought to think of another name. i don't know what though. this is the only idea i had.
if you want to keep the theme maybe like S-Cat or like……………………….. ToT
ummmmmmmmmmmmmm maybe like CatS instead?
pkhead
Scratcher
1000+ posts

wags - WebAssembly to GoboScript

scratchcode1_2_3 wrote:

pkhead wrote:

(#5)

scratchcode1_2_3 wrote:

No…. please don't name it that…

But the tool looks cool….
nooo ignore that definition.. and. its like. ScratchCAT. i conceived this whole clever design for a logo…
fine, maybe i ought to think of another name. i don't know what though. this is the only idea i had.
if you want to keep the theme maybe like S-Cat or like……………………….. ToT
ummmmmmmmmmmmmm maybe like CatS instead?
lazy, but maybe i could call it scrat? theoretically you'd be less likely to think of poop and more likely to think of the movie Ice Age.
pkhead
Scratcher
1000+ posts

wags - WebAssembly to GoboScript

novice27b wrote:

The name could maybe use a little workshopping…

WASM -> Scratch does make a lot of sense though. The main reason is, WASM has no “jump/goto” instruction - and neither does Scratch. Working around this is one of the big challenges with compiling other languages into Scratch, but compilers targeting WASM already solve it!
yes, precisely! although webassembly has the ability to branch out of block nestings of arbitrary depth, which prevents control flow compilation from being trivial. but nonetheless it is much easier than dealing with unstructured control flow.
TimothyLawyer
Scratcher
1000+ posts

wags - WebAssembly to GoboScript

how about wa2gs or way2gs

with the first part a shorter and easier to read abbreviation for webassembly

or wasm2gs for the standard abbreviation

or even shorter wags or swag

i.e., simple webassembly to goboscript converter
pkhead
Scratcher
1000+ posts

wags - WebAssembly to GoboScript

TimothyLawyer wrote:

how about wa2gs or way2gs

with the first part a shorter and easier to read abbreviation for webassembly

or wasm2gs for the standard abbreviation

or even shorter wags or swag

i.e., simple webassembly to goboscript converter
actually wags is a pretty good name to me + i can get it to fit with this idea to pun with cats. i will heavily consider that idea.
Oisthebestletter
Scratcher
500+ posts

wags - WebAssembly to GoboScript

just opened a pr
Oisthebestletter
Scratcher
500+ posts

wags - WebAssembly to GoboScript

even a c hello world fails..?

2026/08/20 14:03:40 unknown section code 2
2026/08/20 14:03:40 unknown section code 4
2026/08/20 14:03:40 unknown section code 7
2026/08/20 14:03:40 unknown section code 9
costumes "assets/blank.svg";

%define U32(x) ((x) % 4294967296)
%define S32(x) ((((x) + 2147483648) % 4294967296) - 2147483648)

list SCATMEM = [0; 16908288];

var imul_a0 = 0;
var imul_a1 = 0;
var imul_b0 = 0;
var imul_b1 = 0;
var imul_mul = 0;
var imul_res = 0;

proc imul a, b {
imul_res = ($a % 4294967296) * ($b % 4294967296);
if imul_res >= 4294967296 {
imul_a0 = $a % 65536;
imul_a1 = floor($a / 65536) % 65536;
imul_b0 = $b % 65536;
imul_b1 = floor($b / 65536) % 65536;
imul_mul = imul_a0 * imul_b0;
imul_res = imul_mul % 65536;
imul_mul = floor(imul_mul / 65536) + imul_a1 * imul_b0 + imul_a0 * imul_b1;
imul_res += (imul_mul % 65536) * 65536;
}
}

var scat_g0 = 65536;
var scat_g1 = 0;
var scat_g2 = 0;

2026/08/20 14:03:40 reading error: parser error: invalid or unsupported opcode: 10
Oisthebestletter
Scratcher
500+ posts

wags - WebAssembly to GoboScript

ok, so.. it seems to put semicolons to separate arrays when goboscript uses commas.

Last edited by Oisthebestletter (Aug. 20, 2026 19:23:45)

pkhead
Scratcher
1000+ posts

wags - WebAssembly to GoboScript

Oisthebestletter wrote:

ok, so.. it seems to put semicolons to separate arrays when goboscript uses commas.
i thought that was the syntax goboscript documented for filling an array with a count of an initial value. maybe I misread the manual.

Oisthebestletter wrote:

even a c hello world fails..?
it is way too early in development to compile hello world at the moment. sorry. function calls are not implemented. let alone loops; that is what I am currently working on.

even then getting hello world using libc's printf/puts functions are not a high priority. i am planning the ability to inject GoboScript code into the compiled output, which can be used to provide the definition of functions which are imported by the WASM module. so you can use that to call the “say” block directly, or append to an output list - and there are implementations of sprintf that don't depend on stdio.h which you can find online. so you can use that to get formatted output. so, all that said, I'll likely implement stdio last - that may be two months in the future. or longer. I am employed unfortunately.

and i think even when there is stdio support (probably by implementing WASI syscalls?), what “writing to standard output” means isn't entirely universal. the user could want it to have a sprite say something; the user could want it to write to an output list; the user could want it for something entirely different, fit for the purpose of their specific project. so i think out-of-the-box, the canonical Hello World by itself wouldn't work because the user also needs to implement a function for writing to stdout. although. I suppose i could just provide an optional built-in support library that makes it so writing to stdout appends to a Scratch list akin to a terminal.
scratchcode1_2_3
Scratcher
1000+ posts

wags - WebAssembly to GoboScript

pkhead wrote:

(#14)
it is way too early in development to compile hello world at the moment. sorry. function calls are not implemented. let alone loops; that is what I am currently working on.

Now before someone shoves the “Please don't announce projects before you release them”, that would only apply to overambitious, unrealistic ideas to which the creator has no scope for and no tangible prototype. This is unfinished, but released
pkhead
Scratcher
1000+ posts

wags - WebAssembly to GoboScript

scratchcode1_2_3 wrote:

pkhead wrote:

(#14)
it is way too early in development to compile hello world at the moment. sorry. function calls are not implemented. let alone loops; that is what I am currently working on.

Now before someone shoves the “Please don't announce projects before you release them”, that would only apply to overambitious, unrealistic ideas to which the creator has no scope for and no tangible prototype. This is unfinished, but released
honestly i might have made the topic too early because it currently cannot compile anything that remotely resembles a practical program haha. but I did feel like it was a good idea to make a thread at this point in time. my reasons of doing so, for the curious:

1. I have a solid understanding of how I'm going to make this, as well as its general development roadmap. I also think a version of it that can actually be somewhat useful can be made within about three weeks. (may be wrong though because i am generally not very good at estimating how long it takes to make something)
2. I think making it earlier allows for larger exposure.
3. Didn't really think about this, but I did need to make sure people were OK with the name before it takes too long to find+replace all instances of the name in its codebase. :p
4. I tend to like to dump my thoughts/experiences during development of any given project. AT is probably a way better place to do so for this one, compared to what I've doing the past two weeks, which was a thread within a “Community” of this Internet Communication Platform (which I cannot name on Scratch) whose members' primary interests is mostly completely unrelated to programming or Scratch…
SuperSonicmario
Scratcher
100+ posts

wags - WebAssembly to GoboScript

pkhead wrote:

scratchcode1_2_3 wrote:

No…. please don't name it that…

But the tool looks cool….
nooo ignore that definition.. and. its like. ScratchCAT. i conceived this whole clever design for a logo…
fine, maybe i ought to think of another name. i don't know what though. this is the only idea i had.
Nah, you're good to go. When I read it, I immediately began humming Scatman's World.
pkhead
Scratcher
1000+ posts

wags - WebAssembly to GoboScript

pkhead wrote:

Oisthebestletter wrote:

ok, so.. it seems to put semicolons to separate arrays when goboscript uses commas.
i thought that was the syntax goboscript documented for filling an array with a count of an initial value. maybe I misread the manual.
ok, I did not misread the manual and I did successfully compile some output earlier which used the semicolon syntax (which I forgot that I did).
Oisthebestletter
Scratcher
500+ posts

wags - WebAssembly to GoboScript

pkhead wrote:

pkhead wrote:

Oisthebestletter wrote:

ok, so.. it seems to put semicolons to separate arrays when goboscript uses commas.
i thought that was the syntax goboscript documented for filling an array with a count of an initial value. maybe I misread the manual.
ok, I did not misread the manual and I did successfully compile some output earlier which used the semicolon syntax (which I forgot that I did).
Are you using the latest compiler?
pkhead
Scratcher
1000+ posts

wags - WebAssembly to GoboScript

Oisthebestletter wrote:

pkhead wrote:

pkhead wrote:

Oisthebestletter wrote:

ok, so.. it seems to put semicolons to separate arrays when goboscript uses commas.
i thought that was the syntax goboscript documented for filling an array with a count of an initial value. maybe I misread the manual.
ok, I did not misread the manual and I did successfully compile some output earlier which used the semicolon syntax (which I forgot that I did).
Are you using the latest compiler?
yeah I guess. are you not using the latest version?

Powered by DjangoBB