-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow blocks to be put into list dropdowns #2194
Comments
Yes. This is also quite useful with variables. Also, it might be useful if there was an "advanced" input into custom blocks. That way we could have things like variable selectors and all the other "hacked" selectors you can get in Scratch 2.0. |
I already suggested this in another issue, but this is a great idea anyway. 👍 |
The main thing I have used this for is copying from one list to another, it has allowed me to make some projects that would have otherwise been impractical to make. Making it so that if there are any operators in the list dropdown it would not be able to create new lists would probably be a good idea, and stop one of the problems with "hacked" blocks, so that you can't use a loop to create thousands of lists. It would also be nice if the old projects that used these "hacks" still work. |
@GreenScripter Right, that's a good discussion point -- what should we do about projects that rely on the automatic creation of a list? We don't want many lists to be made by a user accidentally putting the wrong block into a list dropdown (or, for example, doing something like "forever, add 1 to pick random (1) to (99999)). But we also don't want to break projects that rely on this behavior. It should be noted that you don't need to have a custom block to rely on this; for example, you could create a script which references a list, then delete the list, and the block will still reference the list. And when the block runs, the list will be created, in 2.0. If we remove this functionality, and the list isn't created, the script obviously wouldn't work. |
As for the deleting a list which there are still blocks for, I mean it should only not create a new list if there are any blocks in the list name slot. if there are none it should still create the list. As for breaking projects that need to create lists, either lists would need to be created regardless like in 2.0 or some hacked projects would still not work, though far less of them. Also an alternate project runner could be used on old projects, but I would find that counterintuitive and it would definitely confuse people, especially depending on how remixes and downloading then reuploading would effect it. Also if there was a delay associated with creating a new list when blocks are present in the name slot, then new lists could still be created, it might just take a second or two as if there was a wait block thus preventing too many lists from being made by accident. I have accidentally made a loop that makes tons lists before and it is quite annoying to clean up, since there is no way to mass delete lists. |
This makes sense to me. As you said, some old 2.0 projects might use hacked blocks that also rely on creating lists, but those are probably very, very rare. (I imagine that in most cases of a reporter in a 2.0 list dropdown, whatever list that reporter might return already exists.) |
@towerofnix Just curious if you have a rough idea of what it would take to implement this? I'd really like to add it to a fork to try with students, but I have no idea where to start code-wise. |
@Wowfunhappy Pretty sure you'd just need to change the input to be droppable instead of a normal menu field! Shouldn't be too difficult, just a minor formatting change for the block! Would be a scratch-blocks issue though. Check out this section of code! https://github.com/LLK/scratch-blocks/blob/7575c9a0f2c267676569c4b102b76d77f35d9fd6/blocks_vertical/data.js#L231-L254 |
I was reading this again:
I completely disagree. A script It's not at all unusual for weakly typed languages to have some internal logic for how to cast variables to different types. Scratch should be smart enough to figure out that if I drop a list/variable reporter into a list/variable dropdown, I want to operate on that list or variable, and not its contents. |
In that case, why not just select the list in the dropdown? |
Because the list was passed as a parameter of a custom block. |
For what it's worth, I think I've changed my mind on this after thinking it over more. |
This is a feature request, of course. I'm mostly branching out of discussion in #1030 because that thread is very crowded and it's nice to have a more dedicated spot for discussion of this. (I'm particularly carrying the suggestion from scratchfoundation/scratch-vm#1030 (comment).)
I usually use lists as a way to store a lot of related data. For example, suppose I'm building an RPG game of some sort. I might store the hit points of the players and enemies in two separate lists - "player HP" and "enemy HP". Now, since this is a fairly typical RPG game, I want to make players and enemies disappear from the battle when their HP reaches zero. To keep things simple, I'll just look through all HP values in the list and remove the ones that are equal to or below zero. Here's an example script showing how to do that for the enemies:
This is a fine script, and it works in any version of Scratch (even 1.4). The issue is, I want to do the exact same thing, but for the players also. Since we want to do the same thing twice, this sounds like the perfect use case for a custom block, so I'll quickly make one of those:
Now, we want to perform the exact same operation, but on the "player HP" list instead of "enemy HP". The obvious solution, then, is to add an input to the custom block and put that input in all the dropdowns that say "enemy HP":
This can be called like so:
However, anyone who's tried to make something like this knows the issue with this custom block script; you can't put blocks into the dropdowns of list blocks. There's no way, for example, to have a "length of (HP list)" block, because you can't put "HP list" into the list dropdown.
This means that using a custom block this way is not possible, and we have to duplicate our code instead:
This immediately looks like bad code, but there's no simple solution to it in Scratch.
(A note - as a workaround to this, I tend to merge the player HP and enemy HP lists into a single "character HP" list, and also keep a separate list "character is an enemy?". But this is a bit unwieldy in cases where players are similar to enemies in their "die when HP is 0" behavior but different in other fundamental ways throughout the project.)
Another frequent use case of putting blocks into list dropdowns is using a list as the output of a custom block. For example, suppose I make this simple script:
This is a pretty straight-forward custom block, mostly summarized by its name; it takes all the items in a given input list that are greater than a given value and copies them into a given output list. (Note another version of this script could destructively remove items from the input list instead, and not take an output list at all, because the input list would function as the output list. This would be very similar to the "remove characters with less than 0 HP from (HP list)" block above. The purpose of this above custom block is to show how to do that sort of thing non-destructively - without modifying the input list.)
Making a custom block that is as general as this is almost entirely impossible right now, and definitely impractical. The closest thing is to copy all items into a list that the custom block is hard-coded to use. The custom block would also be hard-coded to add items to a specific output list, which would then have to be copied to the wanted output list. Both of these "copying" steps must be done with a manually-put-together script, because there is obviously no way to create a "copy list 1 to list 2". The final, 2.0-compatible script might look like this:
This obviously is not realistically useful in a project (let alone efficient), and instead, barring the use of hacked blocks as described in #1030, it's required to just duplicate the code for the "put all items of (input list) greater than (value) in (output list)" whenever that sort of behavior is needed.
So the example cases have been made above, and hopefully shown you how difficult it is to write custom blocks that operate on lists; my proposal is simply to allow blocks to be put into list dropdowns.
A common point made against this suggestion is that users might try to put a list reporter into a list dropdown. For example, running the script "add 123 to (my list)", where "my list" is the actual reporter for that list, would not add 123 to "my list"; instead, it would add 123 to the list that is referenced by whatever "my list" reports. This is obviously not what a new user would expect.
However, it's not very difficult to debug that issue. Users who are new to using lists have hopefully played a bit with variables already, and understand that a variable must be selected from the dropdown to work - so it wouldn't come as much surprise that in order for the list blocks to work right, you have to select the list from the dropdown.
Anyhow, sorry for the rather long post, but I figured this would be best understood with examples that compare scripts that would be possible with this suggestion and their current equivalents, which, as seen, are always much more clumsy.
The text was updated successfully, but these errors were encountered: