scratch-vm: Hacked Blocks - Support Argument Hacking

There are many types of “hacked blocks” that are possible in Scratch 2.0. While prior discussions have grouped them all together, we have spent a bunch of time trying to tease apart this landscape so we can understand and hopefully work with the community to support these use cases.

While hacked blocks are uncommon (used by less than 0.01% of shared projects), they are used by some high-profile projects and are interesting to some Scratchers. By far the most common type of hacked block is what we are now referring to as “argument hacking”. This issue attempts to break down this type of hacked block with the hope of soliciting support from the community if they wish for Scratch to continue to support these projects in the future.

Examples

Overriding Menu Options

[
    "keyPressed:",
    "\u0010"
]

image

Making “Non-Droppable” Menus “Droppable”

[
    "penColor:",
    [
        "readVariable",
        "tmp"
    ]
]

image

Overriding Custom Procedure Menu Options

[
    "call",
    "colour %c",
    -3384542
]

image

Use Cases

By far the most commonly seen types of “Argument Hacking” are “Overriding Menu Options” and “Making ‘Non-Droppable’ Menus ‘Droppable’”. In all cases the project JSON is modified to override the arguments for a given opcode. While specific use cases vary from project to project and block to block, we often see this type of modification performed to support applications such as supporting non-standard keyboard events and dynamically controlling “non-droppable” state.

Example Project

https://llk.github.io/scratch-gui/develop/#214566447

Uncaught Error: Serialized variable type with id '}o/;i5r,O`;[HD478%k?-readVariable,scratch' had type list, and does not match variable field that references it: <field xmlns="http://www.w3.org/1999/xhtml" name="VARIABLE" id="}o/;i5r,O`;[HD478%k?-readVariable,scratch" variabletype="">readVariable,scratch</field>.
    at Object.Blockly.Xml.domToFieldVariable_ (lib.min.js:90)
    at Object.Blockly.Xml.domToField_ (lib.min.js:90)
    at Object.Blockly.Xml.domToBlockHeadless_ (lib.min.js:90)
    at Object.Blockly.Xml.domToBlockHeadless_ (lib.min.js:90)
    at Object.Blockly.Xml.domToBlock (lib.min.js:90)
    at Object.Blockly.Xml.domToWorkspace (lib.min.js:90)
    at Object.Blockly.Xml.clearWorkspaceAndLoadFromXml (lib.min.js:90)
    at t.value (lib.min.js:90)
    at t.l (lib.min.js:1)
    at t.n.emit (lib.min.js:12)
    at t.value (lib.min.js:12)
    at t.value (lib.min.js:12)
    at t.value (lib.min.js:132)
    at Object.l [as onClick] (lib.min.js:1)
    at t.value (lib.min.js:90)
    at l (lib.min.js:1)
    at Object.u (lib.min.js:98)
    at Object.invokeGuardedCallback (lib.min.js:106)
    at Object.invokeGuardedCallbackAndCatchFirstError (lib.min.js:106)
    at f (lib.min.js:98)
    at m (lib.min.js:98)
    at b (lib.min.js:98)
    at Array.forEach (<anonymous>)
    at A (lib.min.js:98)
    at w (lib.min.js:98)
    at Jl (lib.min.js:106)
    at Se (lib.min.js:98)
    at batchedUpdates (lib.min.js:98)
    at $ (lib.min.js:98)
    at Te (lib.min.js:98)
    at HTMLDocument.d (raven.js:425)

/cc @kchadha

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 13
  • Comments: 34 (19 by maintainers)

Most upvoted comments

As someone who’s worked with hacked blocks extensively in the past, I can say that most of these have few real use case besides being curiosities.

I think instead of (or in addition to) supporting these hacks, it would be better to provide official methods of doing the things they enable. Hacked blocks have the disadvantage of being difficult to understand and impossible for a regular user to replicate.

Here are two common use cases for argument hacking and how they could be eliminated.

Non-standard key events

Common non-standard key events are shift, backspace, and escape. This could be eliminated by simply adding the keys to the key menu. 😃 Since they wouldn’t be used as often as the existing options, maybe they could be added to the bottom of the menu?

Variable variables

This hack is used to set/get arbitrary variables, similar to PHP’s variable variables. screen shot 2018-04-06 at 15 46 22 The need for this hack could be eliminated by adding dictionaries in addition to lists. screen shot 2018-04-06 at 15 47 17 This would be easier to understand than the hack, and it’s almost certainly a better programming practice. Maybe this could be added as an extension similar to pen?

@Mr-Dave2 I certainly wouldn’t describe the Scratch Team as an “army of programmers” … perhaps a “merry band of programmers”? Point is our team is quite small given the size of product we support (each engineer on the Scratch Team supports ~25 million kids each year). While the most common use case for argument hacking is scheduled to be resolved (the “when key pressed” hat block and “key pressed” boolean reporter) many others are not.

I do not believe it is reasonable to expect the Scratch Team to support all forms of hacked blocks. Those projects which are not supported may not work in Scratch 3.0 and I believe that is a reasonable expectation for projects that were created outside of the Scratch editor. To your point I do think we’ll need to communicate this clearly to the community as we get closer to launch.

That said, I understand that some of these use cases matter deeply to the community (and for the record I think many of them are really neat!). For many of those – as discussed by others in this thread – I’d be more than happy to discuss proposals for how to resolve them and review pull requests which extend support. I hope that helps clarify. 😄

Some users tried to create a “pop” block for list manipulation.

(join (item (last v) of (list v)) (letter (0) of {delete (last v) of (list v)})

I think that this feature is useful enough that a new block could be added that does the same thing.

delete and report item (1) of (list)

Having said that, I do not feel that backwards-compatibility is necessary with these sorts of hacked blocks (ones which use stack blocks as reporters), as these types of hacked blocks are incredibly infrequent.

Of course, if custom reporters are implemented, then not only will the above block be easy to implement by a user, it’ll also teach a lot more about how the block works, and will prepare them for programming in functional languages

I am working on the “Overriding Custom Procedure Menu Options” one. Hopefully some fixes on sb2.js seems working.

@towerofnix

I’d have a go at this, but I don’t really know where to start - if I’m not mistaken, dropdown inputs that don’t normally accept blocks fundamentally cannot accept blocks (i.e. they contain no slot for a block to exist in), and I’m not sure how to work around that. (Contrast this to Scratch 2.0, where the only difference between a droppable and not-droppable input is a simple flag!)

We are in the middle of migrating all blocks to be “extensions” this month and I think that may help provide a more simple / flexible entry point. Stay tuned, I think some of this may become easier to approach soon.

“Gallery of the Bizarre”, should have a less flashy animation

Whoops. Yup. Fixed.

Scratch 3.0 has heavy validation on its JSON format. However, if we don’t allow ‘hacked’ Scratch 3.0 files, we make it hard for users to remix projects in the Scratch 3.0 editor, if the projects they are remixing are using hacked blocks.

Should Scratch 3.0 validation be relaxed to match Scratch 2.0?


I propose an additional mode, differing from the regular one, where reporters can be dragged into any slot, regardless of shape (a bit like Snap!'s behaviour, where the slot shapes are guides rather than restrictions). This mode would be automatically enabled (with a notice provided to the user to explain what the mode does and the risks associated with it), when one attempts to enter the editor of a ‘hacked’ project; but it could also be enabled manually somehow. (Name of mode; text to use for mode; or how to access it manually–up for discussion too).

This would also resolve the issue of validation: it could be very very relaxed, and we’d just need to show the notice.

What are the thoughts on such a mode?

A few suggestions: Operators to convert types (stack - reporter, reporter - boolean, boolean - number reporter, boolean - string reporter, text reporter - string reporter, string reporter - stack, etc.), make all menus droppable, and reporters with stacks in them. Then, block “hacking” wouldn’t be needed.

I liked what thisandagain said in his original post about reaching out to the community. I’ve looked at a number hacked block projects and forum posts and I’d guess many Scratchers believe hacked blocks to be an assumed right. And I’d be a little concerned if on the day you release Scratch 3.0 it unexpectedly breaks a number of popular and formally featured projects. Now might be a good time to have a respected Scratcher sort of sit down with us and explain the realities of using undocumented software features. I sure many people won’t need this but I believe that it would be a kindness to the community to give us a heads up.