Scratch-blocks: Implement custom procedures

Created on 18 Sep 2016  路  32Comments  路  Source: LLK/scratch-blocks

Lots of people's 2.0 custom blocks won't make any sense when converted into the new format.

For example this:

Would presumably become something like this in the conversion from 2.0 to 3 format

Scratchers might get confused by things like this.

custom procedures feature

Most helpful comment

Todo:

  • [ ] Spec 3.0 'Define' Block
  • [ ] Spec 3.0 Using Custom Procedures
  • [ ] Spec 3.0 Dragging Custom Procedures to other Sprites
  • [ ] Spec 3.0 Dragging Custom Procedures to the Backpack

Scratch 3.0 - Round 1 - Create a Custom Procedure Behaviors

Clicking 'Make a Block' opens Dialog

  • From within the 'More Blocks' category, user clicks 'Make a block'
    r1 5 2_gui_make-a-block_1

  • 'Make a Block' dialog opens
    r1 5 2_gui_make-a-block_2

Closing 'Make a Block' Dialog

  • User can close by clicking transparent background
  • User can close by clicking the ( x ) icon in the upper left
  • User can close by clicking the 'Cancel' button
    r1 5 2_gui_make-a-block_3

'Naming' a block

  1. User clicks the 'text label' field (transparent black)
    r1 5 2_gui_make-a-block_4

  2. Once the field has focus the user can edit the text, in this case the user has highlighted 'block'
    r1 5 2_gui_make-a-block_5

  3. User deletes the text to rename the block
    r1 5 2_gui_make-a-block_6

  4. Important to note the default size of the block 'name' field, this is inline with the minimum block width as seen in the specs below.

    • The block will not grow until the text extends beyond the orange line. screen shot 2017-02-22 at 2 53 12 pm

    • Or if the text is shorter than the orange line and an input is added, the input start here screen shot 2017-02-22 at 2 49 47 pm

  5. User renames block 'dance'
    r1 5 2_gui_make-a-block_7

  6. User clicks out of field, so it loses focus
    r1 5 2_gui_make-a-block_8

Exposing more options

By default, 'More options' is collapsed.

  1. User clicks 'More Options'
    r1 5 2_gui_make-a-block_9

  2. 'More options' are exposed in an accordion animation. The dropdown arrow flips and the text changes to 'Less options'
    r1 5 2_gui_make-a-block_10

Options Include (different from 2.0)

  • Add input: number or text
  • Add input: boolean
  • Add label
  • Run without screen refresh

_Language (e.g. 'Add input: number or text') subject to change._

Adding inputs / labels

  1. User clicking 'Add input: number or text' input. A number/text input is added to the block with the text highlights.
    _Default language that appears in a newly added input will need refinement_
    r1 5 2_gui_make-a-block_11

  2. User changes text within the input.
    r1 5 2_gui_make-a-block_12
    This eventually will become the reporter block within the 'definition' block. screen shot 2017-02-22 at 4 43 11 pm
    _This is not a block definition design, just a concept sketch to illustrate the point above._

  3. User adds an addtional label and enters text
    r1 5 2_gui_make-a-block_13

_In a future iteration we might want to explore the ability to reposition inputs / labels._

Editing inputs / labels

  1. User can navigate between inputs and labels by clicking the element they would like to change.
    r1 5 2_gui_make-a-block_14

  2. User updates the text they previously entered
    r1 5 2_gui_make-a-block_15

Deleting inputs / labels

  1. User accidentally adds a boolean
    r1 5 2_gui_make-a-block_16

  2. User clicks the delete icon
    r1 5 2_gui_make-a-block_17

Check / Uncheck 'Run without Screen Refresh'

r1 5 2_gui_make-a-block_18

All 32 comments

The current implementation is a direct copy-paste from Blockly - the actual version is only in the earliest design stages, and is likely to look significantly different. @carljbowman

From @TheBrokenRail:

Here's Some Issues I Found With The UI in procedure blocks/custom blocks

  • [ ] Need Space Between Blocks In Block Palate
  • [ ] Input Block Is Offset From Curser
  • [ ] No Background For Warning About Standalone report block Needing To Be Used In a custom block definition
  • [ ] Needs Proper UI for input Selection
  • [ ] Gear And Warning Triangles should be maybe should be the same color as the blocks
  • [ ] Use Define Instead of to
  • [x] Bottom of define with report is longer than top

One more:

  • Need to be able to add label text between inputs

Yep, and inputs need types (number, string, boolean).

Don't forget default values for number/string inputs! That's implemented in the actual "blocks" part of Scratch 2.0 (though there's no UI for it atm).

Moved from #631:

image

The define part is hard to read because of the color of the text.

Also the red outline is _really_ red. It's kind of hard to see. Later on the shape will probably be changed to look like a stack (or reporter) outline but for now the color should probably be fixed anyways.

Reasons for the same color as the outline of stack blocks:

  • It _is_ the outline of a block.
  • It represents a block more clearly.

Reasons for a lighter or different color:

  • It's actually the outline of a preview of what the block will look like, generally, so it distinguishes between a real block and a preview.
  • It looks similar to how custom block definitions currently look.

Also probably more but just some observations. :)

When selecting the name field it gets all big and weird and when closing even bigger fort a moment, can you change it to be like other text fields?

@TheBrokenRail I believe that's actually an unrelated bug with text fields not in shadow blocks. If you'd like that could be filed and fixed separately!

@dekrain points out we need to generate shadow blocks:
pseudo-fields
https://github.com/LLK/scratch-blocks/issues/665

We need padding between the define and report blocks in the block palate

For custom reporter definitions, I like the idea of dragging the standalone "report" block out from the bottom of the c-block to copy it, just like we do with procedures' arguments in 2.0

Why were custom reporters removed?

Why were toolbox removed

With The New Changes We should also a "create procedure dialog"

@dekrain The toolbox is not removed.
@TheBrokenRail We never implemented custom reporters in the first place. What was there before was a copy from Blockly.

I was really hoping for custom reporters, it would have been a great feature.

@TheBrokenRail Whether we have this feature is independent of whether it currently exists in the scratch-blocks code. We have a lot of work to do to support custom blocks.

Model (not view) questions:
-- Who keeps the master list of procedures? I assume it'll be the VM
-- How does the VM tell blockly about the list of procedures?
-- Does that information need to be passed back and forth at any time other than when opening the "More Blocks" section of the toolbox?
---- If it's only at that one point, does Blockly need an explicit list of procedures, or can we get away with just replacing procedures.js:flyoutCategory()?
-- What is the unique identifier for a procedure?
---- Will you allow multiple procedures with the same name + same named arguments in Scratch 3.0? _Scratch 2.0 allows this, but I consider it a bug. It means that the definition of your procedure at runtime depends on which block you least recently interacted with._
-- How will you handle multiple procedures with the same name + arguments that are implemented differently in different workspaces?
-- Will it be possible to define procedures for the whole project, or only for individual sprites?
-- What happens if you drag a procedure call from one sprite to another sprite?

@thisandagain @cwillisf Assigning for feedback on Rachel's questions above

Will you allow multiple procedures with the same name + same named arguments in Scratch 3.0? _Scratch 2.0 allows this, but I consider it a bug. It means that the definition of your procedure at runtime depends on which block you least recently interacted with._

I also consider this a bug. I suggest that if two procedures "become" identical then we add a disambiguating suffix to the name of the one that caused the ambiguity, just like we do with sprites and costumes and such. That is, foo becomes foo2 upon collision.

If we end up in a situation where there's ambiguity, for example if someone hand-edits their project files to see what happens, then I think any result other than crashing / throwing is fine. IMO predictable-but-strange behavior, like that of Scratch 2.0, is almost a bonus in this situation since it likely means we have a tinkerer and they might enjoy puzzling it out to glean insight into our implementation.

"Any result other than crashing / throwing" includes, for example, if scratch-blocks decides to show only one instance of the procedure in the palette despite there being two definitions in the workspace. I would prefer to preserve the two definitions' bodies, if that's feasible. The VM can do whatever is convenient with the duplicate definition, such as (effectively) throwing / overwriting one with the other.

Will it be possible to define procedures for the whole project, or only for individual sprites?

We've talked about this occasionally on the Scratch team but haven't settled on a good way to present it to the user. If there's a reasonable way to leave room for this as a possibility I think that would be a good idea, but I don't believe it's in the plans at the moment.

What happens if you drag a procedure call from one sprite to another sprite?

I'm in favor of the current Scratch 2.0 behavior where the block is copied to the destination sprite but doesn't do anything meaningful there unless a matching procedure exists there. This makes it easier to copy a big block of code and then adjust it after the copy. Maybe we'd want to show that the call is in an error state somehow, but I think that's a nice-to-have.

How will you handle multiple procedures with the same name + arguments that are implemented differently in different workspaces?

I think this is OK to leave in the hands of the VM: the VM knows which sprite a block is running against and can look up the right procedure using that knowledge. On the VM side, I'm sure procedures' info will be stored in such a way that they're associated with a particular context. We'll just need to know the name and argument types that the block believes it should be calling, and the VM will be responsible for looking up the right procedure from there. If that information is encoded into a single ID-like value (C++ name mangling, anyone?) then that might improve performance of procedure-heavy projects. On the other hand, I don't believe procedure lookup is a common bottleneck so I don't think that finding such an encoding is strictly necessary.

(That's not to say that there are no projects for which procedure lookup is a bottleneck. I've accepted a few PRs in scratch-flash from some of our power-users where they claimed to see significant performance gains by optimizing procedure lookup...)

Will it be possible to define procedures for the whole project, or only for individual sprites?

We've talked about this occasionally on the Scratch team but haven't settled on a good way to present it to the user. If there's a reasonable way to leave room for this as a possibility I think that would be a good idea, but I don't believe it's in the plans at the moment.

Out of curiosity, why is procedures available for all sprites any less clear than variables for all sprites? I understand the clarity issue, but isn't that just as much of an issue with global variables? Is it specifically the location of the definition?

If we treat global procedures like we do global variables then I can see possible compatability issues with 2.0. If procedures in the stage automatically become global then there could be name collision issues

Why would we need to be concerned about compatibility going from 3.0 to 2.0? I don't think you could load 2.0 projects into 1.4, could you?

@LFP6 The compatibility issue is from 2.0 to 3.0, when there's custom blocks of the same name in the Stage and another sprite.

Now I know what is wrong! In https://github.com/LLK/scratch-blocks/blob/develop/blocks_vertical/procedures.js#L57 it should be

container.setAttribute(name, value);

instead of

var el = document.createElement(name)
el.setAttribute('value', value);
container.appendChild(el);

or in domToMutation.

@carljbowman Note for default "input" label from discussion with @ntlrsk:
Pico Cricket used box1, box2, etc. rather than "input" or "thing" which worked well.

Todo

  • [ ] Document 2.0 Using Custom Procedures
  • [ ] Document 2.0 Dragging Custom Procedures to other Sprites
  • [ ] Document 2.0 Dragging Custom Procedures to the Backpack

Scratch 2.0 - Create a Custom Procedure Behaviors

Clicking 'Make a Block' opens Dialog

make block dialog mov

'Naming' block

name-block mov

As @cwillisf mentioned there is no unique identifier that is displayed to the user. For example, in the image below, there are two custom procedures with the same name: 'dance'. It not clear which custom procedure will be called when the 'dance' block on the workspace is executed.
screen shot 2017-02-16 at 3 03 22 pm

This issue becomes even more complicated when moving custom procedures to other sprites. More related info will be documented.

Exposing more 'Options'

more-options mov
Options Include

  • Add number input
  • Add string input
  • Add boolean input
  • Add text label
  • Run without screen refresh toggle

Adding inputs / labels

adding props mov

Editing inputs / labels

edit fields mov

Deleting inputs / labels

delete prop mov

Check / Uncheck 'Run without screen refresh

check-uncheck mov

Clicking 'ok' to confirm block

ok-to-block mov

Todo:

  • [ ] Spec 3.0 'Define' Block
  • [ ] Spec 3.0 Using Custom Procedures
  • [ ] Spec 3.0 Dragging Custom Procedures to other Sprites
  • [ ] Spec 3.0 Dragging Custom Procedures to the Backpack

Scratch 3.0 - Round 1 - Create a Custom Procedure Behaviors

Clicking 'Make a Block' opens Dialog

  • From within the 'More Blocks' category, user clicks 'Make a block'
    r1 5 2_gui_make-a-block_1

  • 'Make a Block' dialog opens
    r1 5 2_gui_make-a-block_2

Closing 'Make a Block' Dialog

  • User can close by clicking transparent background
  • User can close by clicking the ( x ) icon in the upper left
  • User can close by clicking the 'Cancel' button
    r1 5 2_gui_make-a-block_3

'Naming' a block

  1. User clicks the 'text label' field (transparent black)
    r1 5 2_gui_make-a-block_4

  2. Once the field has focus the user can edit the text, in this case the user has highlighted 'block'
    r1 5 2_gui_make-a-block_5

  3. User deletes the text to rename the block
    r1 5 2_gui_make-a-block_6

  4. Important to note the default size of the block 'name' field, this is inline with the minimum block width as seen in the specs below.

    • The block will not grow until the text extends beyond the orange line. screen shot 2017-02-22 at 2 53 12 pm

    • Or if the text is shorter than the orange line and an input is added, the input start here screen shot 2017-02-22 at 2 49 47 pm

  5. User renames block 'dance'
    r1 5 2_gui_make-a-block_7

  6. User clicks out of field, so it loses focus
    r1 5 2_gui_make-a-block_8

Exposing more options

By default, 'More options' is collapsed.

  1. User clicks 'More Options'
    r1 5 2_gui_make-a-block_9

  2. 'More options' are exposed in an accordion animation. The dropdown arrow flips and the text changes to 'Less options'
    r1 5 2_gui_make-a-block_10

Options Include (different from 2.0)

  • Add input: number or text
  • Add input: boolean
  • Add label
  • Run without screen refresh

_Language (e.g. 'Add input: number or text') subject to change._

Adding inputs / labels

  1. User clicking 'Add input: number or text' input. A number/text input is added to the block with the text highlights.
    _Default language that appears in a newly added input will need refinement_
    r1 5 2_gui_make-a-block_11

  2. User changes text within the input.
    r1 5 2_gui_make-a-block_12
    This eventually will become the reporter block within the 'definition' block. screen shot 2017-02-22 at 4 43 11 pm
    _This is not a block definition design, just a concept sketch to illustrate the point above._

  3. User adds an addtional label and enters text
    r1 5 2_gui_make-a-block_13

_In a future iteration we might want to explore the ability to reposition inputs / labels._

Editing inputs / labels

  1. User can navigate between inputs and labels by clicking the element they would like to change.
    r1 5 2_gui_make-a-block_14

  2. User updates the text they previously entered
    r1 5 2_gui_make-a-block_15

Deleting inputs / labels

  1. User accidentally adds a boolean
    r1 5 2_gui_make-a-block_16

  2. User clicks the delete icon
    r1 5 2_gui_make-a-block_17

Check / Uncheck 'Run without Screen Refresh'

r1 5 2_gui_make-a-block_18

Is there any info on the timeline around this feature?

@MichaelZawadzki Yes, currently this is scheduled for the end of the year. Of course we have a lot of plates in the air, so that could change.

I鈥檓 don鈥檛 really like the fact that number and text inputs are combined - it adds ambiguity to which input type the block shows up as (is it number or string?) and removes the ability to ensure a number for inputs that should be numbers.

Was this page helpful?
0 / 5 - 0 ratings