(Redirected from Workarounds)

This article is a list of block workarounds, which are scripts that recreate the effect of a block without using the block. They can be used to better understand how blocks work or to recreate a block in another programming language or framework which may only have simpler functions. (shift+scroll to show hidden parts of code)

Motion Blocks

Block Workaround
move (steps) steps
go to x: ((x position) + (([sin v] of (direction)) * (steps))) y: ((y position) + (([cos v] of (direction)) * (steps)))

or

change x by (([sin v] of (direction)) * (steps))
change y by (([cos v] of (direction)) * (steps))
turn right (angle) degrees
point in direction ((direction) + (angle))
turn left (angle) degrees
point in direction ((direction) - (angle))
go to (random position v)
go to x: (pick random (-240) to (240)) y: (pick random (-180) to (180))

or

glide (0) secs to x: (pick random (-240) to (240)) y: (pick random (-180) to (180))
go to (mouse-pointer v)
go to x: (mouse x) y: (mouse y)
go to (wanted sprite v)
go to x: ([x position v] of (wanted sprite v)) y: ([y position v] of (wanted sprite v))

or

set x to: ([x position v] of (wanted sprite v))
set y to: ([y position v] of (wanted sprite v))
go to x: (x) y: (y)
set x to (x)
set y to (y)

or

glide (0) secs to x: (x) y: (y)

or

repeat until <<(x position) = (x)> and <(y position)=(y)>> // x and y must be integers
go to (random position v) // This script may be laggy
end
glide (secs) secs to (random position v)
glide (secs) secs to x: (pick random (-240) to (240)) y: (pick random (-180) to (180))
glide (secs) secs to (mouse-pointer v)
glide (secs) secs to x: (mouse x) y: (mouse y)
glide (secs) secs to (wanted sprite v)
glide (secs) secs to x: ([x position v] of (wanted sprite v)) y: ([y position v] of (wanted sprite v))
glide (secs) secs to x: (x) y: (y)
set [speedx v] to (((x) - (x position)) / ((secs) * (30))
set [speedy v] to (((y) - (y position)) / ((secs) * (30))
repeat ((secs) * (30))
change x by (speedx)
change y by (speedy)
point in direction (direction:: variables)
turn cw ((direction:: variables) - (direction)) degrees

or

turn ccw ((-1) * ((direction:: variables) - (direction))) degrees
point towards (mouse-pointer v)
point in direction (([atan v] of (((mouse x) - (x position)) / ((mouse y) - (y position)))) + ((180) * <not <(mouse y) > (y position)>>))
point towards (wanted sprite v)
point in direction (([atan v] of ((([x position v] of (wanted sprite v)) - (x position)) / (([y position v] of (wanted sprite v)) - (y position)))) + ((180) * <not <([y position v] of (wanted sprite v)) > (y position)>>))
point towards (random direction v)
point in direction (pick random (-180) to (179))
change x by (x position change)
set x to ((x position) + (x position change))
set x to (x)
change x by ((x) - (x position))
change x by (((x position) * (-1)) + (x))
go to x: (x) y: (y position)
change y by (y position change)
set y to ((y position) + (y position change))
set y to (y)
change y by ((y) - (y position))
change y by (((y position) * (-1)) + (y))
go to x: (x position) y: (y)
(x position)
([x position v] of (wanted sprite v))
(y position)
([y position v] of (wanted sprite v))
(direction)
([direction v] of (wanted sprite v))

Looks Blocks

Block Workaround
say (text) for (secs) seconds
say (text)
wait (secs) seconds
say []
think (text) for (secs) seconds
think (text)
wait (secs) seconds
think []
switch costume to (wanted costume)
define switch to costume // run without screen refresh
repeat until <<(wanted costume) = (costume [number v])> or <(wanted costume) = (costume [name v])>>
next costume
end
next costume
switch costume to ((costume [number v]) + (1))

or

switch costume to (join [next costume] []) 
switch backdrop to (wanted backdrop)
define switch to backdrop // run without screen refresh
repeat until <<(wanted backdrop) = (backdrop [number v])> or <(wanted backdrop) = (backdrop [name v])>>
next backdrop
end
next backdrop
switch backdrop to ((backdrop [number v]) + (1))

or

switch backdrop to (next backdrop v)
change size by (amount)
set size to ((size) + (amount))%
set size to (wanted size)%
change size by ((wanted size) - (size))
clear graphic effects
set [color v] effect to (0)
set [fisheye v] effect to (0)
set [whirl v] effect to (0)
set [pixelate v] effect to (0)
set [mosaic v] effect to (0)
set [brightness v] effect to (0)
set [ghost v] effect to (0)
hide
switch costume to (blank costume v) // Doesn't actually hide the sprite, just changes to a costume that is blank
go to [front v] layer
go [forward v] ((1)/(0)) layers // 1/0 = Infinity

or:

go [backward v] ((-1)/(0)) layers // -1/0 = -Infinity
go to [back v] layer
go [forward v] ((-1)/(0)) layers // -1/0 = -Infinity

or:

go [backward v] ((1)/(0)) layers // 1/0 = Infinity

or

when green flag clicked
change [sprites v] by (1) // In every sprite

go [backward v] ((sprites)- (1)) layers
(costume [number v])
([costume # v] of (wanted sprite v))
Note Note: This workaround will not work with clones.
(costume [name v])
([costume name v] of (wanted sprite v))
Note Note: This workaround will not work with clones.
(backdrop [number v])
([backdrop # v] of (Stage v))
(backdrop [name v])
([backdrop name v] of (Stage v))
(size)
([size v] of (wanted sprite v))
Note Note: This workaround will not work with clones.

Sound Blocks

Block Workaround
play sound (wanted sound v) until done
start sound (wanted sound v)
wait (length of sound) seconds // has to be measured
start sound (wanted sound v)
. . .
broadcast (continue script v)
play sound (wanted sound v) until done

when I receive [continue script v]
. . .
change volume by (amount)
set volume to ((volume) + (amount))%
set volume to (amount) %
change volume by ((amount) - (volume))
(volume)
([volume v] of (wanted sprite v))

Event Blocks

Block Workaround
when green flag clicked
when I receive [Scratch-StartClicked v]
. . .
Note Note: Only works offline in Scratch 1.x.
when [timer v] > (-1) // This is a block that can not be stopped
if <<<(mouse y) = [180]> and <mouse down?>> or <(clicked?) = [0]>> then
set [clicked? v] to [1]
. . .

or

when [timer v] > (-1)
broadcast (start v)

when I receive [start v]//Put this in every sprite.
when [space v] key pressed
when [timer v] > (-1)
forever
wait until <key (space v) pressed?>
. . .

or

when [timer v] > (-1) // This is a block that can not be stopped, therefore you can make a workaround that does not require the green flag to be clicked
forever
wait until <key (space v) pressed?>
. . .
wait until <not <key (space v) pressed?>>

when this sprite clicked
when [timer v] > (-1) // This is a block that can not be stopped, therefore you can make a workaround that does not require the green flag to be clicked
forever
  wait until <<touching (mouse-pointer v) ?> and <mouse down?>> //This is not an exact workaround because you could, first, while not touching the sprite, hold down your mouse, then, still holding down your mouse, move it over to the sprite. This will not activate the true block but will activate this.

  . . .

or

when [timer v] > (-1) // This is a block that can not be stopped, therefore you can make a workaround that does not require the green flag to be clicked
forever
if <<mouse down?> and <touching (mouse-pointer v) ?>> then
set [down? v] to [1]
wait until <not <mouse down?>>
set [down? v] to [0]
end
end // This makes sure the script will not activate if you are holding down the mouse and then move it onto the sprite.

when [timer v] > (-1) // This is a block that can not be stopped, therefore you can make a workaround that does not require the green flag to be clicked
forever
if <<touching (mouse-pointer v) ?> and <<mouse down?> and <(down?) = [0]>>> then
. . .
end
when stage clicked
when [timer v] > (-1) // This is a block that can not be stopped, therefore you can make a workaround that does not require the green flag to be clicked
forever
if <mouse down?> then
set [down? v] to [1]
wait until <not <mouse down?>>
set [down? v] to [0]
end
end // This makes sure the script will not activate if you are holding down the mouse and then move it onto the sprite.

when [timer v] > (-1) // This is a block that can not be stopped, therefore you can make a workaround that does not require the green flag to be clicked
forever
if <<mouse down?> and <(down?) = [0]>> then
. . .
end
when backdrop switches to [background v]
when [timer v] > (-1) // This is a block that can not be stopped, therefore you can make a workaround that does not require the green flag to be clicked
if <([backdrop name v] of (Stage v)) = []> then // There goes the backdrop name
. . .
end

or

when [timer v] > (-1) // This is a block that can not be stopped, therefore you can make a workaround that does not require the green flag to be clicked
forever
  wait until <([backdrop name v] of (stage v)) = []> // There goes the backdrop name
  ...
end
when [loudness v] > (wanted loudness)
when gf clicked // You can not use the greater than block to work around the green flag, because the greater than block is the block you want to work around
forever
  wait until <(loudness) > (wanted loudness)>
  . . .

or

when [timer v] > ((timer) - <(loudness) > (wanted loudness)>
broadcast (message v)
when gf clicked
set [broadcasted? v] to [0]
. . .
set [broadcasted? v] to [1]

when gf clicked
forever
wait until <(broadcasted?) = [1]>
. . .
set [broadcasted? v] to [0]
end

or

broadcast (broadcast v) and wait
when I receive [broadcast v]
. . . // Whatever comes after the broadcast, in addition to the receive block you would have
broadcast (message v) and wait
when gf clicked
set [broadcasted? v] to [0]
set [wait v] to [0]
. . .
set [broadcasted? v] to [1]
set [wait v] to [1]
wait until <(wait) = [0]>
. . .

when gf clicked
forever
wait until <(broadcasted?) = [1]>
. . .
set [broadcasted? v] to [0]
set [wait v] to [0]
end

or

set [wait v] to [3] // However many receive blocks you have for that particular broadcast
broadcast (broadcast v)
wait until <(wait) = [0]>

when I receive [broadcast v]
. . .
change [wait v] by (-1) // Be sure to put this right before any "stop script" blocks, too!

Control Blocks

Block Workaround
wait (number) seconds
rest for (((tempo) / (60)) * (number)) beats

or

reset timer
wait until <not <(timer) < (number)>>
// If one is using other scripts that involve the timer, this might mess them up

or

say [] for (number) seconds
// This will mess up anything the sprite is already saying

or

glide (number) secs to x:(x position) y:(y position)

or

set [time v] to ((days since 2000) * (86400))
wait until <(((days since 2000) * (86400)) - (time)) > (number)>
repeat (# of Times)
...
end
set [counter v] to [0]
repeat until <(counter) = (# of Times)>
change [counter v] by (1)
. . .
end

or

repeat (# of times) of times

define repeat (number) of times
...
if <not<(number:: custom) = [1]>> then
repeat ((number:: custom) - (1)) of times
forever
...
end
repeat until <> // Put no boolean in the block or put a boolean that will always equals false (1=2).
. . .
end

or

repeat ([10 ^ v] of (309)) // The reason this works is because Scratch will compute 10 ^ 309 as Infinity, because it is a very large number.
  . . .
end

or

repeat (join [Infinity] [])
...
end

or

repeat ((1)/(0))
...

or

when gf clicked
Forever Loop:: custom

define Forever Loop // Do not run without screen refresh
...
Forever Loop:: custom

or

when gf clicked
broadcast (loop v)

when I receive [loop v]
...
broadcast (loop v)

or

when gf clicked
switch backdrop to (backdrop1 v)

when backdrop switches to [backdrop1 v]
...
switch backdrop to (backdrop1 v)

or

when gf clicked
hide
create clone of (myself v)

when I start as a clone
...
wait [0] seconds // To avoid crashing Scratch
create clone of (myself v)
delete this clone
if <. . .::grey> then
. . .
end
if <. . .:: grey> then
. . .
else
// Put no blocks here.
end

or

broadcast <. . .:: grey> and wait

when I receive [true v]
. . .

or

repeat until <not <. . . :: grey>>
broadcast (true v)
stop [this script v]
end
broadcast (continue v)

when I receive [true v]
. . .
// Whatever would be in if
broadcast (continue v)

when I receive [continue v]
. . .

or

repeat <. . . :: grey>
. . . :: gray
end
if <. . .::grey> then
. . .
else
. . .
end
if <. . .::grey> then
. . .
end
if <not <. . .::grey>> then
. . .
end

or

repeat <. . . :: grey>
. . . :: gray
end
repeat <not <. . . :: grey>>
. . . :: gray
end

or

if <. . .::grey>::custom stack
define if <boolean>
if <boolean> then
. . . // Whatever would be in if
stop [this script v]
end
. . . // Whatever would be in else
wait until <. . .::grey>
repeat until <. . .::grey>
// Put no blocks in the loop.
end
repeat until <. . .::grey>
. . .
define loop // do not run without screen refresh
if <not <. . .:: grey>> then
. . .
loop
end

or

broadcast (loop v)

when I receive [loop v]
if <not <. . . :: grey>> then
. . .
broadcast (loop v)
end

or

forever
...
if <. . . :: grey> then
broadcast (Continue v)
stop [this script v]
end
end

when I receive [Continue v]
...
stop [all v]
broadcast (stop all v)

when I receive [stop all v] // It must be put in every Sprite and the Stage.
stop [other scripts in sprite v]
clear graphic effects
clear sound effects
stop [this script v]
wait until <> // Put no boolean in the block.

or

wait ([10 ^ v] of (309)) seconds // These do not actually *stop* the script, the block starts and ends after 10^1024 milliseconds due to Unix time overflow

or

wait ((1)/(0)) seconds // Same applies to the above comment, but it also returns an error in the offline editor.
or
rest for ([10^ v] of (309)::operators) beats::music
or
rest for ((1)/(0)) beats::music

or

forever
// Put no blocks here.

or

repeat until <>//Put no booleans here
// The above workarounds for this block don't work in custom blocks since they don't really stop the script.

or

define Example
. . .
broadcast (Stop this script v)

when I receive [Stop this script v]
. . .//Continue what was before the custom block
when i start as a clone
set [clone v] to [1]
create clone of (myself v)
broadcast (clone startup v)
set [clone v] to [0]

when i receive [clone startup v]
if <(clone) = [1]> then
. . .
end

Sensing Blocks

Block Workaround
ask [] and wait
say (question)
delete all of [answer v]
set [count v] to [0]
repeat until <<touching (mouse-pointer v)?> and <mouse down?>>
if <key (a v) pressed?> then
change [count v] by (1)
insert [A] at (count) of [answer v]
end
if <key (b v) pressed?> then
change [count v] by (1)
insert [B] at (count) of [answer v]
end
if <key (c v) pressed?> then
change [count v] by (1)
insert [C] at (count) of [answer v]
end
if <key (d v) pressed?> then
change [count v] by (1)
insert [D] at (count) of [answer v]
end
if <key (e v) pressed?> then
change [count v] by (1)
insert [E] at (count) of [answer v]
end
if <key (f v) pressed?> then
change [count v] by (1)
insert [F] at (count) of [answer v]
end
if <key (g v) pressed?> then
change [count v] by (1)
insert [G] at (count) of [answer v]
end
if <key (h v) pressed?> then
change [count v] by (1)
insert [H] at (count) of [answer v]
end
if <key (i v) pressed?> then
change [count v] by (1)
insert [I] at (count) of [answer v]
end
if <key (j v) pressed?> then
change [count v] by (1)
insert [J] at (count) of [answer v]
end
if <key (k v) pressed?> then
change [count v] by (1)
insert [K] at (count) of [answer v]
end
if <key (l v) pressed?> then
change [count v] by (1)
insert [L] at (count) of [answer v]
end
if <key (m v) pressed?> then
change [count v] by (1)
insert [M] at (count) of [answer v]
end
if <key (n v) pressed?> then
change [count v] by (1)
insert [N] at (count) of [answer v]
end
if <key (o v) pressed?> then
change [count v] by (1)
insert [O] at (count) of [answer v]
end
if <key (p v) pressed?> then
change [count v] by (1)
insert [P] at (count) of [answer v]
end
if <key (q v) pressed?> then
change [count v] by (1)
insert [Q] at (count) of [answer v]
end
if <key (r v) pressed?> then
change [count v] by (1)
insert [R] at (count) of [answer v]
end
if <key (s v) pressed?> then
change [count v] by (1)
insert [S] at (count) of [answer v]
end
if <key (t v) pressed?> then
change [count v] by (1)
insert [T] at (count) of [answer v]
end
if <key (u v) pressed?> then
change [count v] by (1)
insert [U] at (count) of [answer v]
end
if <key (v v) pressed?> then
change [count v] by (1)
insert [V] at (count) of [answer v]
end
if <key (w v) pressed?> then
change [count v] by (1)
insert [W] at (count) of [answer v]
end
if <key (x v) pressed?> then
change [count v] by (1)
insert [X] at (count) of [answer v]
end
if <key (y v) pressed?> then
change [count v] by (1)
insert [Y] at (count) of [answer v]
end
if <key (z v) pressed?> then
change [count v] by (1)
insert [Z] at (count) of [answer v]
end
if <key (0 v) pressed?> then
change [count v] by (1)
insert [0] at (count) of [answer v]
end
if <key (1 v) pressed?> then
change [count v] by (1)
insert [1] at (count) of [answer v]
end
if <key (2 v) pressed?> then
change [count v] by (1)
insert [2] at (count) of [answer v]
end
if <key (3 v) pressed?> then
change [count v] by (1)
insert [3] at (count) of [answer v]
end
if <key (4 v) pressed?> then
change [count v] by (1)
insert [4] at (count) of [answer v]
end
if <key (5 v) pressed?> then
change [count v] by (1)
insert [5] at (count) of [answer v]
end
if <key (6 v) pressed?> then
change [count v] by (1)
insert [6] at (count) of [answer v]
end
if <key (7 v) pressed?> then
change [count v] by (1)
insert [7] at (count) of [answer v]
end
if <key (8 v) pressed?> then
change [count v] by (1)
insert [8] at (count) of [answer v]
end
if <key (9 v) pressed?> then
change [count v] by (1)
insert [9] at (count) of [answer v]
end
if <key (right arrow v) pressed?> then
change [count v] by (1)
end
if <key (left arrow v) pressed?> then
change [count v] by (-1)
end
if <key (space v) pressed?> then
change [count v] by (1)
insert [] at (count) of [answer v]
end
wait (0.001) seconds
end
(distance to (sprite v))
([sqrt v] of (((([x position v] of (wanted sprite v)) - (x position)) * (([x position v] of (wanted sprite v)) - (x position))) + ((([y position v] of (wanted sprite v)) - (y position)) * (([y position v] of (wanted sprite v)) - (y position)))))
(mouse x)
 go to (mouse-pointer v)
 set [Mouse Position v] to (x position)
(mouse y)
 go to (mouse-pointer v)
 set [Mouse Position v] to (y position)
(days since 2000)
set [d v] to ((((367) * (current [year v])) - ([floor v] of (((7) * ((current [year v]) + ([floor v] of (((current [month v]) + (9)) / (12))))) / (4)))) + ((([floor v] of (((275) * (current [month v])) / (9))) + (current [day v])) - (730530)))
if <(d) < [-36435]> then
    change [d v] by (1)
end
if <(d) < [-72990]> then
    change [d v] by (1)
end
if <(d) > [36585]> then
    change [d v] by (-1)
end
change [d v] by (-1) // Where d = days since 2000

 // Correct from 1800-2199

(timer)
set [timestamp v] to (days since 2000)
forever
set [timer v] to ((86400) * ((days since 2000) - (timestamp)))
end
reset timer
//Only works with the previous workaround
when I receive [reset timer v] //broadcast this message when resetting the timer
set [timestamp v] to (days since 2000) //resets the timer
set drag mode [draggable v]
when this sprite clicked
repeat until <not <<mouse down?> and <touching (mouse-pointer v)?>>
go to x: (mouse x) y: (mouse y)

Operators Blocks

Block Workaround
((a) + (b))
((a) - ((b) * (-1)))

or

((a) - ((0) - (b)))

or

set [answer v] to (a)
change [answer v] by (b)
((a) - (b))
((a) + ((b) * (-1)))

or

((a) + ((b) / (-1)))

or

((a) + (join [-](b))) // Only works when b is positive

or

set [answer v] to (a)
change [answer v] by ((-1) * (b))
((a) * (b))
((a) / ((1) / (b)))

or

delete all of [num1 numbers v]
delete all of [num2 numbers v]
delete all of [product digits v]
set [dec pos 1 v] to [0]
set [count v] to [0]
repeat (length of (a))
    change [count v] by (1)
    if <not<(letter (count) of (a)) = [-]>> then
        if <(letter (count) of (a)) = [.]> then
            set [dec pos 1 v] to ((length of (a)) - (count))
        else
            add (letter (count) of (a)) to [num1 numbers v]
        end
    end
end
set [dec pos 2 v] to (0)
set [count v] to (0)
repeat (length of (b))
    change [count v] by (1)
    if <not <(letter (count) of (b)) = [-]>> then
        if <(letter (count) of (b)) = [.]> then
            set [dec pos 2 v] to ((length of (b)) - (count))
        else
            add (letter (count) of (b)) to [num2 numbers v]
        end
    end
end
set [num1 v] to (num1 numbers)
set [num2 v] to (num2 numbers)
set [product v] to [0]
repeat (num1)
    change [product v] by (num2)
end
set [decimal position v] to ((dec pos 1) + (dec pos 2))
set [count v] to [0]
repeat (length of (product))
    change [count v] by (1)
    add (letter (count) of (product)) to [product digits v]
end
repeat until <[0] < ((length of [product digits v]) - ((decimal position) - (1)))>
    insert (0) at (1) of [product digits v]
end
insert [.] at ((length of [product digits v]) - ((decimal position) - (1))) of [product digits v]
if <not <<(a) < [0]> = <(b) < [0]>>> then
    insert [-] at (1) of [product digits v]
end
set [product v] to ((product digits) + (0))
Note Note: The result of this workaround is stored in the (product) variable.

or

set [product v] to [0]
if <(a) < [0]> then
    repeat ([abs v] of (a))
        change [product v] by ((0) - (b))
    end
else
    repeat (a)
        change [product v] by (b)
    end
end
Note Note: This workaround does not work when the (a) value is not an integer.
((a) / (b))
if <(b) < (0)> then
  set [result v] to (((a) * ([e ^ v] of ((-1) * ([ln v] of ((-1) * (b)))))) * (-1))
else
  set [result v] to ((a) * ([e ^ v] of ((-1) * ([ln v] of (b)))))
end

or

set [counter v] to [0]
set [dividend v] to []
set [decimal point v] to [0]
repeat (length of (a))
    change [counter v] by (1)
    if <(letter (counter) of (a)) = [.]> then
        set [decimal point 1 v] to ((length of (a)) - (counter))
    else
        if <not <(letter (counter) of (a)) = [-]>> then
            set [dividend v] to (join(dividend)(letter (counter) of (a)))
        end
    end
end
set [counter v] to [0]
set [divisor v] to [0]
set [decimal point 2 v] to [0]
repeat (length of (b))
    change [counter v] by (1)
    if <(letter (counter) of (b)) = [.]> then
        set [decimal point 2 v] to ((length of (b)) - (counter))
    else
        if <not <(letter (counter) of (b)) = [-]>> then
            set [divisor v] to (join(disivor)(letter (counter) of (b)))
        end
    end
end
set [remainder v] to []
set [calculating v] to []
set [conuter v] to [0]
repeat (. . .:: grey) // set precision
    change [counter v] by (1)
    if <(length of (dividend)) < (counter)> then
        set [remainder v] to (join(remainder)(0))
    else
        set [remainder v] to (join(remainder)(letter (counter) of (dividend)))
    end
    set [greatest factor v] to [0]
    repeat until <(remainder) < ((divisor) * (greatest factor))>
        change [greatest factor v] by (1)
    end
    if <(remainder) < ((divisor) * (greatest factor))> then
        change [greatest factor v] by (-1)
    end
    set [calculating v] to (join(calculating)(greatest factor))
    set [remainder v] to ((remainder) - ((greatest factor) * (divisor)))
end
set [counter v] to [0]
set [quotient v] to []
repeat (length of (calculating))
    change [counter v] by (1)
    set [quotient v] to (join(quotient)(letter(counter) of (calculating)))
    if <(((length of (dividend)) - (decimal point 1)) + (decimal point 2)) = (length of (quotient))> then
        set [quotient v] to (join(quotient)[.])
    end
end
if <not<<(a) < [0]> = <(b) < [0]>>> then
    set [quotient v] to (join[-](quotient))
end
Note Note: The result is stored in the (quotient) variable
<(a) > (b)>
<(b) < (a)>

or

<not <<(a) < (b)> or <(a) = (b)>>>

or

<not<([abs v] of ((b) - (a))) = ((b) - (a))>>
Note Note: This workaround does not work with strings.
<(a) < (b)>
<(b) > (a)>

or

<not <<(a) > (b)> or <(a) = (b)>>>

or

<not<([abs v] of ((a) - (b))) = ((a) - (b))>>
Note Note: This workaround does not work with strings.
<(a) = (b)>
<not <<(a) < (b)> or <(a) > (b)>>>

or

<(a) contains (b)?> and <(b) contains (a)?>

or

delete all of [list v]
add (a) to [list v]
if <[list v] contains (b)?> then
  . . .
end
<<> and <>>
if <. . . :: grey> then
if <. . . :: grey> then
. . .
end
end

or

<not <<not <. . . :: grey>> or <not <. . . :: grey>>>>

or

set [var v] to [0]
repeat until <(var) = [1]>
. . . // Your block here, C-blocks loop inside
if <> then
set [var v] to [1]
end // This works for all current boolean-accepting blocks

or

if <> then
if <> then
set [return v] to [true]
else
set [return v] to [false]
end
else
set [return v] to [false]

or

<(<. . . :: grey> + <. . . :: grey>) > (1)>
<<> or <>>
if <. . . :: grey> then
. . .
else
if <. . . :: grey> then
. . .
end
end

or

<not <<not <. . . :: grey>> and <not <. . . :: grey>>>>

or

if <> then
set [return v] to [true]
else
if <> then
set [return v] to [true]
else
set [return v] to [false

or

<(<. . . :: grey> + <. . . :: grey>) > (0)>
<not <>>
<<. . . :: grey> = [false]>

or

if <> then
//Put no blocks here.
else
. . .
(join [][])
set [count v] to [0]
set [output v] to []
repeat (length of (a)) // a is the first input
change [count v] by (1)
add (letter (count) of (a)) to [final v]
end
set [count v] to (0)
repeat (length of (b)) // b is the second input
change [count v] by (1)
add (letter (count) of (b)) to [final v]
end
set [output v] to (final) // This is the final string

or

// This only works if they're both whole numbers and b is positive
set [return v] to []
repeat (length of ())
set [return v] to ((return) * (10))
end
change [return v] by ()
(letter (1) of [])
// Only works for whole numbers and the letter you're looking for must be 1
if <[] > [0]> then
set [return v] to []
repeat ((length of ()) - (1))
set [return v] to ([floor v] of ((return) / (10)))
end
else
set [return v] to [-]
end
// Al that's needed is a way to cut off the front digits.
(length of [])
set [return v] to [1]
repeat until <(letter ((return) + (1)) of ()) = []>
change [return v] by (1)
end
(() mod ())
if <(round ((a) / (b))) > ((a) / (b))> then
set [remainder v] to ((a) - ((round (((a) / (b)) - (0.5))) * (b)))
else
set [remainder v] to ((a) - ((round ((a) / (b))) * (b)))
end

or

define (#) mod (div)
set [Result v] to (#::custom)
repeat until <<(Result) < (0)> or <(Result) = (0)>>
  change [Result v] by ((0) - (div::custom))
end
repeat until <<(Result) > (0)> or <(Result) = (0)>>
  change [Result v] by (div::custom)
end
(round ())
set [result v] to (0)
repeat (input)
change [result v] by (1)
end

or

set [report v] to []
set [count v] to [1]
repeat until <<(letter (count) of (num)) = [.]> or <(count) = (length of (num))>>
set [report v] to (join (report) (letter (count) of (num)))
change [count v] by (1)
end
if <<(letter (count) of (num)) = [.]> and <(letter ((count) + (1)) of (num)) > (4)>> then
change [report v] by (1)
end

or

set [return v] to [0]
set [b v] to []
repeat until <([abs v] of (b)) < (1)>
if <[] < [0]> then
change [return v] by (1)
change [b v] by (-1)
else
change [return v] by (-1)
change [b v] by (1)
end
end

or

define round (#)::custom
set [count v] to [1]
repeat until <(letter (count) of (#))=[.]
change [count v] by [1]
end
change [count v] by [1]
if <(letter (count) of (#))=[5]> then
set [round v] to ([ceiling v] of (#))
else
if <(letter (count) of (#))>[5]> then
set [round v] to ([ceiling v] of (#))
else
if <(letter (count) of (#))<[5]> then
set [round v] to ([floor v] of (#)
end
end
end

or

if <(Input) = (0)> then
  set [Output v] to (0)
else
  set [Difference Floor v] to ((Input) - ([floor v] of (Input))
  if <<(Difference Floor) < (0.5)> or <(Difference Floor) = (0.5)>> then
    set [Output v] to ([floor v] of (Input))
  else
    set [Output v] to ([ceiling v] of (Input))
  end
end
([sin v] of (a))
([cos v] of ((a) - (90)))
([cos v] of (a))
go to x: (0) y: (0)
point in direction (a)
move (1) steps
set [result v] to (y position)

or

([sin v] of ((90) - (a)))
([10 ^ v] of ())

abs (absolute value):

set [output v] to (number)
if<(output) < (0)> then
set [output v] to ((-1) * (output))
end

or

set [output v] to (([sqrt v] of ((input) * (input))) + (0))

sqrt (square root):

set [output v] to (input)
repeat until <(output) = (input)>
set [output v] to ((((output) * (output)) + (input)) / ((2) * (output)))
end

or

set [output v] to ([e ^ v] of ((0.5) * ([ln v] of (input))))

ln (natural logarithm):

set [output v] to (([log v] of (input)) / (0.434294481903252))

e ^:

set [output v] to ([10 ^ v] of ((input) / (2.302585092994046)))

log (base 10 logarithm):

set [output v] to (([ln v] of (input)) / ([ln v] of (10)))

10 ^:

set [output v] to ([e ^ v] of ((input) * ([ln v] of (10))))

floor:

set [output v] to (round ((input) - (0.5)))

ceil (ceiling):

set [output v] to (round ((input) + (0.49999999)))

sin (sine):

set [output v] to ([cos v]  of ((90) - (input)))

or

go to x:(0) y:(0)
point in direction (input)
move (1) steps
set [Output v] to (x position)

cos (cosine):

set [output v] to ([sin v]  of ((90) - (input)))

or

go to x:(0) y:(0)
point in direction ((90) - (input))
move (100) steps
set [Output v] to ((x position) / (100)) // Note: only works to 2 decimal places.

tan (tangent):

set [output v] to (([sin v] of (input)) / ([cos v] of (input)))

Data Blocks

Variables Blocks

Block Workaround
(variable)
([public variable v] of (Stage v))
([personal variable v] of (Sprite1 v))
set [ v] to []
change [variable v] by ((amount) - (variable)) 
Note Note: Only works with numbers.
change [ v] by ()
set [variable v] to ((variable) + (amount))

List Blocks

Block Workaround
(list::list)
set [count v] to [0]
set [all are 1 v] to [true]
repeat until <<(all are 1) = [false]> or <(count) > (length of [list v])>>
change [count v] by (1)
if <(length of (item (count) of [list v])) > [1]> then
set [all are 1 v] to [false]
end
end
if <(all are 1) = [true]> then
set [report v] to []
set [count v] to [0]
repeat (length of [list v])
change [count v] by (1)
set [report v] to (join (report) (item (count) of [list v]))
end
else
set [report v] to (item (1) of [list v])
set [count v] to [1]
repeat ((length of [list v]) - (1))
change [count v] by (1)
set [report v] to (join (report) (join [] (item (count) of [list v])))
end
end
add [] to [ v]
insert (item) at (length of [list v]::list) of [list v]
replace item [] of [ v] with []
delete (position) of [List v]
insert (item) at (position) of [List v]
<[ v] contains []?>
define list contains (string)
set [report v] to [false]
set [count v] to [0]
repeat (length of [list v])
change [count v] by (1)
if <(item (count) of [list v]) = (string)> then
set [report v] to [true]
stop [this script v]
end
end

or

if <not <(item # of [] in [list v]) = [0]>> then
. . .
end
(item # of [] in [ v])
define item # of (string) in list
set [result v] to [0]
if <[list v] contains (string)?> then
  repeat until <(item (result) of [list v]) = (string)>
    change [result v] by (1)
  end
end
delete () of [ v]
delete all of [queue v]
set [counter v] to [0]
repeat (length of [list v])
change [counter v] by [1]
add (item (count) of [list v]) to [queue v]
end
delete all of [list v]
set [counter v] to [0]
repeat (length of [queue v])
change [counter v] by [1]
if <not <(item # of (item (item number) of [queue v]) in [queue v]) = (item number)>> then
add (item (count) of [queue v]) to [list v]
end
end
delete all of [queue v]

This will not work with the input "last".

delete all of [ v]
repeat until <(length of [list v]) = [0]>
delete (1) of [list v]
end

or

delete (join [all] ()) of [ v]
length of [ v]
set [item number v] to (1)// This will only fail if one of the items in the list is blank
set [length v] to (0)
repeat until <(item (item number) of [list v]) = ()>
change [item number v] by (1)
change [length v] by (1)
end

Music Blocks

Block Workaround
rest for (beats) beats
 wait (((60) / (tempo)) * (beats)) seconds
set tempo to (amount)
change tempo by ((amount) - (tempo))
change tempo by (amonut)
set tempo to ((tempo) + (amount))

Pen Blocks

Block Workaround

stamp

set [stamping? v] to [true]
create clone of (myself v)
set [stamping? v] to [false]

when I start as a clone // and any other hat blocks
if <(stamping?) = [true]> then
stop [this script v]
end
Note Note: Will contribute to the 300 clone limit and also will be removed with "delete this clone" blocks.

erase all

broadcast (clear v)// This whole script only works if you use the stamping workaround

when I receive [clear v]
if <(stamping) = [true]> then
delete this clone
end

set [Old Costume v] to (costume [number v])// Put this script in a sprite that has the background image
switch costume to (Background v)
stamp
switch costume to (Old Costume)
...

Motor Blocks

Block Workaround
turn motor on for (1) seconds :: wedo
turn motor on :: wedo
wait (number) seconds
turn motor off :: wedo
motor off::extension
turn motor on for (0) seconds :: wedo

or

set motor power (0)::extension

PicoBoard Blocks

Archive.png This article or section documents something not included in the current version of Scratch (3.0). It is only useful from a historical perspective.
Block Workaround
<sensor [A connected? v]:: extension>
<([resistance A v] sensor value:: extension) < [10]>//Resistance A through D

Removed Blocks

Block Workaround
start scene (scene1 v)::control
broadcast (scene1 v)
when <> is true :: hat events
when gf clicked
forever
  if <. . . :: grey> then
    . . .
  end
end

or

when gf clicked
forever
wait until <. . .::grey>
. . .
wait until <not<. . .::grey>>
end

or

when [timer v] > ((timer) - <. . . :: grey >
... // If you want it to repeatedly happen until the boolean is false, use the repeat until and put a not (boolean here) block inside it.
forever if <>::control
forever
if <. . . :: grey> then
. . .
end
define all at once
// Run without screen refresh
. . .
create clone::control
create clone of (myself v)
change costume by (1)::looks
switch costume to ((costume [number v]) + (1))
change background by (1)::looks
switch backdrop to ((backdrop [number v]) + (1))
say nothing::looks
say []

or

think []
hide all sprites::looks
broadcast (hide all sprites v)

and

when I receive [hide all sprites v] // Put this in every sprite
hide
stamp transparent (Ghost)::pen
set [ghost v] effect to (Ghost)
stamp
set [ghost v] effect to (0)
(abs ()::operators)
([abs v] of ())

or see Operators Blocks

(sqrt ()::operators)
([sqrt v] of ())

or see Operators Blocks

<loud?::sensing>
<(loudness) > [30]>
Note Note: The loudness value that this block checks was changed from 30 in previous versions of Scratch, to 10 in Scratch 2.0.
(Scratch days::sensing)
((days since 2000) - (2691))
(user id::sensing)
when gf clicked
if <not <[☁ users v] contains (username)?>> then
if <not<(username)=()>> then
add (username) to [☁ users v]
end
end
set [user id v] to (item # of (username) in [☁ users v])

then use

say (join [Your User ID is ] (user id::variables))

or

if <(user id::variables) = [insert User ID number you want here]> then
 . . .
end

depending on what you want to make.

Note Note: This will not work until cloud lists are added which has been rejected by the Scratch Team, but you could also backpack a cloud list engine from another user or use this.
Comment
//Right Click anywhere on scripts area -> "add comment"

or

define comment:(comment)//Put no blocks in the define

then use,

comment:[your comment here]::custom

Experimental Blocks

Block Workaround
(camera motion::sensing)
(video (motion v) on (sprite v))
(camera direction::sensing)
(video (direction v) on (sprite v))
(counter::control)
(counter) // Using a variable
incr counter::control
change [counter v] by (1)
clear counter::control
set [counter v] to [0]
while <> {
}@loopArrow ::control
repeat until <not <. . .:: grey>>
    . . .
end
for each [i v] in (10){
}::control
set [i v] to [0]
repeat (. . .:: grey)
    change [i v] by (1)
    . . .
end

or

set [i v] to [0]
repeat until <(i) = (. . .:: grey)>
    change [i v] by (1)
    . . .
end

Non-Existent Blocks

Note Tip: You can create some of these blocks using My Blocks
Block Workaround
<[ v] received?::events>
when I receive [something v]
set [something received v] to [true]
. . .
set [something received v] to [false]

or

when I receive [something v]
set [something received v] to [true]
wait (0.5) seconds
set [something received v] to [false]

then

if <(something received) = [true]> then
. . .

or

when I receive [something v]
set [something received v] to [true]
broadcast (something REAL v) and wait
set [something received v] to [false]

The reason this is not existent is for too much ambiguity. The two above is a workaround for the version when the message is done running and/or where it is only "true" for half a second. Below is one that is true if it was received it since the green flag was clicked.

when gf clicked
set [something received v] to [false]

when I receive [something v]
set [something received v] to [true]

and then simply use

<(something received) = [true]>

as the block you want to work around. Below is one that returns false when another broadcast is received

when I receive [EVERYOTHERBROADCAST (duplicate and replace) v]
set [something received v] to [false]

and the variable is the same. There is one more thing you can do, since the project was created, but you'll need to be a Scratcher in order to use it. Delete the first block on the second workaround, and make the variable a cloud variable

draw [circle v] with perimeter (100)::pen Circle:
repeat (360)
  move ((perimeter)/(360)) steps
  turn right (1) degrees
end

Triangle:

repeat (3)
  move ((perimeter)/(3)) steps
  turn right (120) degrees
end

Square:

repeat (4)
  move ((perimeter)/(4)) steps
  turn right (90) degrees
end

Other regular polygons:

repeat (number of sides)
  move ((perimeter)/(number of sides)) steps
  turn right ((360)/(number of sides)) degrees
end
stop [all and press green flag v]
broadcast [Scratch-StartClicked v]

when I receive [Scratch-StartClicked v]
...
Note Note: Only works offline in Scratch 1.x

or

when green flag clicked
...
//and
when green flag clicked
forever
reset timer
end
when [timer v]>(0.1)
forever
reset timer
end
when [timer v]>(0.1)
...
Note Note: Make sure there are only two 'when green flag clicked' and two 'when [timer v]>(0.1)' blocks
Note Note: Make sure code marked as '...' are the same
Note Note: This method disables all timer uses for counting time. To fix this, use the 'days since 2000' for the timer
reset timer
repeat until <not<(timer) < (secs::grey)>>
. . .
end

or

set [timer offset v] to ((timer) + (secs::grey))
repeat until <not<(timer) < (timer offset)>>
. . .
end

or

set [time v] to ((days since 2000)*(86400))
repeat until <not<(((days since 2000)*(86400))-(time))<(secs::grey)>>
. . .
end
when I receive [Spawn v]
. . .

broadcast (Spawn v)
<clone?::control>
when I start as a clone
set [clone? v] to [true] // Create a variable for this sprite only, non-clones are set to false

or

set [clone? v] to [true]
create clone of (myself v)
set [clone? v] to [false]
change by x: () y: ()::motion
go to x: ((x position) + (X)) y: ((y position) + (Y))

or

change x by (X)
change y by (Y)
glide () secs by x: () y: ()::motion
glide (seconds) secs to x: ((x position) + (X)) y: ((y position) + (Y))
glide () secs () steps::motion
glide (seconds) secs to x: ((x position) + (([sin v] of (direction)) * (steps))) y: ((y position) + (([cos v] of (direction)) * (steps)))
point towards x: () y: ()::motion
point in direction (([atan v] of (((X) - (x position)) / ((Y) - (y position)))) + (<(y position) > (Y)> * (180)))
(distance to x: () y: ()::sensing)
([sqrt v] of ((((x position) - (wanted x)) * ((x position) - (wanted x))) + (((y position) - (wanted y)) * ((y position) - (wanted y)))))
stop ask::sensing stack
...
broadcast(stop ask 1 v
stop[all v
when I receive[stop ask 1 v]//put in every sprite
broadcast(stop ask 2 v
when I receive[stop ask 2 v]//put in every sprite
...
Note Note: This workaround will clear all graphic effects and delete all clones.
<ask in progress?::sensing>
set [ask in progress? v] to [true]
ask [...] and wait
set [ask in progress? v] to [false]
<sprite clicked?::sensing>
when this sprite clicked
set [sprite clicked? v] to [true]
wait until <not <<mouse down?> and <touching (mouse-pointer v)?>>>
set [sprite clicked? v] to [false]

or

 <<mouse down?> and <touching (mouse-pointer v)?>>
show all sprites::looks
broadcast (show all sprites v)

and

when I receive [show all sprites v] // Put this in every sprite
show
previous costume::looks
switch costume to ((costume [number v]) - (1))

or

switch costume to (previous costume v) // Select a costume named "previous costume" and then delete it

or

switch costume to (join[previous costume][])
previous backdrop::looks
switch backdrop to ((backdrop [number v]) - (1))

or

switch backdrop to (previous backdrop v) // already selectable

or

switch backdrop to (join[previous backdrop][])
((a) ^ (v):: operators)
Note Note: The first three workarounds will not work properly for negative bases (such as trying to compute (-2)5.
(round ([10 ^ v] of ((v) * ([log v] of ([abs v] of (a))))))

or

(round ([e ^ v] of ((v) * ([ln v] of ([abs v] of (a))))))

or

([10 ^ v] of ((v) * ([log v] of (a)))

or

if <(letter (1) of (power)) = (-)> then
repeat ((0) - (power))
set [ans v] to ((ans)/(base))
end
else
repeat (power)
set [ans v] to ((ans)*(base)
end
end
<true::operators>
<not <>> // Put no boolean in the not block.

or

<[0] = [0]> // Same input on both slots.
<false::operators>
<not <not <>>> // Put no boolean in the second not block.

or

<<> and <>> // Put no booleans in the and block.

or

<<> or <>> // Put no booleans in the or block.

or

<[0] = [1]>
<[] ≠ []::operators>
<not <[] = []>>
<[] ≥ []::operators>
<not <[] < []>>

or

<<(input 1) > (input 2)> or <(input 1) = (input 2)>>

or

<(input 1) > ((input 2) - (1))>
Note Note: This workaround only works for integers.
<[] ≤ []::operators>
<not <[] > []>>

or

<<(input 1) < (input 2)> or <(input 1) = (input 2)>>

or

<(input 1) < ((input 2) + (1))>
Note Note: This workaround only works for integers.
(if <> then [] else []::operators)
if <condition::grey> then
set [report v] to (true)
else
set [report v] to (false)

or

(((true) * <condition::grey>) + ((false) * <not <condition::grey>>))
Note Note: Only works with numbers. If you want to use strings, use the first one above.
(letters () through () of []::operators)
set [report v] to []
set [count v] to (a) // a is the first letter
repeat until <(count) = ((b) + (1))> // b is the last letter
set [report v] to (join (report) (letter (count) of (text)))
change [count v] by (1)
end
(digit () of ()::operators)
(([floor v] of ((number) / ([10 ^ v] of (([floor v] of (digit)) - (1))))) mod (10))
(round () to the nearest ()::operators)
((round ((round what) / (to the nearest))) / ((1)/(to the nearest)))

or

((round ((number) * ([10 ^ v] of (number of places)))) / ([10 ^ v] of (number of places)))
([ v] effect::looks)
forever
set [color v] effect to (effect)
<sound ( v) playing?::sound>
set [playing v] to [true]
play sound (wanted sound v) until done
set [playing v] to [false]
play sound ( v) for (1) beats::sound
play sound (wanted sound v)
rest for (1) beats
stop all sounds
(instrument::music)
forever
set instrument to (instrument)
change item (1) of [ v] by (1)::list
replace item (1) of [wanted list v] with ((item (1) of [wanted list v]) + (1))
if <> then
forever
when @stopSign clicked::events hat
forever
reset timer
end
when [timer v] > (0.1)
...

or

when gf clicked
forever
set [timer+ v] to ((timer) + (0.2))
. . .
end
when [timer v] > (timer+)
. . .
<<> xor <>::operators>
<<<. . . :: grey> or <. . . :: grey>> and <not <<. . . :: grey> and <. . . :: grey>>>> // The nth input of the or must be the same as the nth input of the and

or

<(<. . . ::grey> + <. . . ::grey>) = [1]>

or

<not <<. . . ::grey> = <. . . ::grey>>>
<(. . .) is a number?::operators>
<((. . .) + (0)) = (. . .)>

<shown?::looks>

set [shown v] to []
go to (wanted sprite v)
if <touching (wanted sprite v)?> then
set [shown v] to [1]//1 means true, 0 means false
else
set [shown v] to [0]
end

or

show
set [(wanted sprite)shown v] to [true]//Replace for all show blocks

hide
set [(wanted sprite)shown v] to [false]//Replace for all hide blocks

or

broadcast [hide v]//To hide
broadcast [show v]//To show

when I receive [hide v]
hide
set [shown v] to [false]

when I receive [show v]
show
set [shown v] to [true]
Note Note: Replace with all show/hide blocks in the wanted sprite.

stop[all scripts in this sprite v]::controls cap

stop[other scripts in sprite v]
stop[this script v]

hide all variables::variables

hide variable [ v]//With the field empty
Note Warning: This workaround contains a hacked block made by editing the JSON of a project. If someone does not want to edit the JSON of a project, the block can be picked up in the block palette of Scratch 2.0. The file can then be loaded in Scratch 3.0
Cookies help us deliver our services. By using our services, you agree to our use of cookies.