Discuss Scratch

cookieclickerer33
Scratcher
1000+ posts

Chloe’s first class list extension

Note: all the images you see here are pictures of this extension running in scratch, no trickery!

I made a custom extension that adds first class lists, copy the code from the below area and then in turbowarp press “load from url” then “load from text” then paste it in, if you want no 1 frame delay for the blocks running you have to make the extension unsandboxxed.
class ListExtension {
constructor(runtime) {
this.runtime = runtime;
this.customList = [];
}
getInfo() {
return {
id: 'listextension',
name: 'First class lists',
color1: '#ff0000', // Red
color2: '#e83600', // Dark red orange
color3: '#9e0514', // reddish brown
blocks: [
{
opcode: 'listItems',
blockType: Scratch.BlockType.REPORTER,
text: 'list [ITEM1] and [ITEM2]',
arguments: {
ITEM1: {
type: Scratch.ArgumentType.STRING,
defaultValue: 'Item 1',
},
ITEM2: {
type: Scratch.ArgumentType.STRING,
defaultValue: 'Item 2',
},
},
},
{
opcode: 'getItemAtIndex',
blockType: Scratch.BlockType.REPORTER,
text: 'item [INDEX] of [LIST]',
arguments: {
INDEX: {
type: Scratch.ArgumentType.NUMBER,
defaultValue: 1,
},
LIST: {
type: Scratch.ArgumentType.BLOCK,
defaultValue: {
opcode: 'lists_create_with',
type: Scratch.ArgumentType.LIST,
},
},
},
},
{
opcode: 'indexInList',
blockType: Scratch.BlockType.REPORTER,
text: 'the [FIRSTORLAST] index of [ITEM] in [LIST]',
arguments: {
FIRSTORLAST: {
type: Scratch.ArgumentType.DROPDOWN,
menu: 'firstLast',
defaultValue: 'first',
},
ITEM: {
type: Scratch.ArgumentType.STRING,
defaultValue: 'Item',
},
LIST: {
type: Scratch.ArgumentType.BLOCK,
defaultValue: {
opcode: 'lists_create_with',
type: Scratch.ArgumentType.LIST,
},
},
},
},
{
opcode: 'indicesOf',
blockType: Scratch.BlockType.REPORTER,
text: 'indices of [ITEM] in [LIST]',
arguments: {
ITEM: {
type: Scratch.ArgumentType.STRING,
defaultValue: 'Item',
},
LIST: {
type: Scratch.ArgumentType.BLOCK,
defaultValue: {
opcode: 'lists_create_with',
type: Scratch.ArgumentType.LIST,
},
},
},
},
{
opcode: 'listAttribute',
blockType: Scratch.BlockType.REPORTER,
text: 'get [ATTRIBUTE] of [LIST]',
arguments: {
ATTRIBUTE: {
type: Scratch.ArgumentType.DROPDOWN,
menu: 'listAttributes',
defaultValue: 'length',
},
LIST: {
type: Scratch.ArgumentType.BLOCK,
defaultValue: {
opcode: 'lists_create_with',
type: Scratch.ArgumentType.LIST,
},
},
},
},
{
opcode: 'setItemAtIndex',
blockType: Scratch.BlockType.REPORTER,
text: 'set item [INDEX] to [ITEM] in [LIST]',
arguments: {
INDEX: {
type: Scratch.ArgumentType.NUMBER,
defaultValue: 1,
},
ITEM: {
type: Scratch.ArgumentType.STRING,
defaultValue: 'New Item',
},
LIST: {
type: Scratch.ArgumentType.BLOCK,
defaultValue: {
opcode: 'lists_create_with',
type: Scratch.ArgumentType.LIST,
},
},
},
},
],
menus: {
firstLast: {
acceptReporters: false,
items: ['first', 'last'],
},
listAttributes: {
acceptReporters: false,
items: ['length', 'reverse'], // Add more options as needed
},
},
};
}
listItems(args) {
return args.ITEM1 + '\n' + args.ITEM2;
}
getItemAtIndex(args) {
const index = args.INDEX;
const list = args.LIST;
if (list) {
// Split the list by newline characters.
const items = list.split('\n');
if (index >= 1 && index <= items.length) {
// Return the item at the specified index.
return items[index - 1];
}
}
// Return an empty string if there's no list or the index is out of bounds.
return '';
}
indexInList(args) {
const firstOrLast = args.FIRSTORLAST;
const item = args.ITEM;
const list = args.LIST;
items: ['first', 'last']
if (list) {
// Split the list by newline characters.
const items = list.split('\n');
const indices = [];
// Find all indices where the item appears.
for (let i = 0; i < items.length; i++) {
if (items[i] === item) {
indices.push(i + 1); // Adding 1 to match Scratch's indexing.
}
}
if (indices.length > 0) {
if (firstOrLast === 'first') {
return indices[0]; // Return the first index.
} else if (firstOrLast === 'last') {
return indices[indices.length - 1]; // Return the last index.
}
}
}
// Return an empty string if there's no list or the item is not found.
return '';
}
indicesOf(args) {
const item = args.ITEM;
const list = args.LIST;
if (list) {
// Split the list by newline characters.
const items = list.split('\n');
const indices = [];
// Find all indices where the item appears.
for (let i = 0; i < items.length; i++) {
if (items[i] === item) {
indices.push(i + 1); // Adding 1 to match Scratch's indexing.
}
}
return indices.join('\n'); // Join indices with newline characters.
}
// Return an empty string if there's no list.
return '';
}
listAttribute(args) {
const attribute = args.ATTRIBUTE;
const list = args.LIST;
if (list) {
// Split the list by newline characters.
const items = list.split('\n');
if (attribute === 'length') {
return items.length;
} else if (attribute === 'reverse') {
return items.reverse().join('\n'); // Reverse the list and join with newline characters.
}
}
// Return an empty string if there's no list or for unsupported attributes.
return '';
}
setItemAtIndex(args) {
const index = args.INDEX;
const newItem = args.ITEM;
const list = args.LIST;
if (list) {
// Split the list by newline characters.
const items = list.split('\n');
if (index >= 1 && index <= items.length) {
// Replace the item at the specified index with the new item.
items[index - 1] = newItem;
return items.join('\n'); // Join the modified list with newline characters.
}
}
// Return the original list if there's no list or the index is out of bounds.
return list;
}
}
Scratch.extensions.register(new ListExtension());
Here’s the rundown of all the blocks you see here:

The
(list [a] and [b] :: list)
Block returns a first class list with the items specified, if you want more than 2 items do
(list [a] and (list [b] and [c] :: list) :: list)
This returns a list containing a,b,c
(item (1) of (\ \ \:: #590101):: list)
Returns the item number specified of the first class list of the second input
(The [first v] index of [thing] in (\ \ \:: #590101)::list)
(The [last v] index of [thing] in (\ \ \:: #590101)::list)
Returns the item number of the first or last item that is the same as the provided string
For example

And

The
(Indices of [thing] in (\ \ \:: #590101):: list)
Block returns a list of all the item numbers that match the provided string, as an example:


The
(Set item (1) to [thing] in (\ \ \:: #590101):: list)
Block works just like
replace item ( v) of [list v] with [thing]
But with first class lists

And finally there’s
(Get [length v] of (\ \ \:: #590101) :: list)
(Get [reverse v] of (\ \ \:: #590101)::list)
The “length” option returns the amount of items in the list, and the “reverse” option returns the list with the item numbers of each item swapped (so the first item becomes the last, the last becomes the first etc.)

You can set these to variables just fine and they display properly, there’s also no trickery here, the system just works with no caviots


I hope you all like this!

Last edited by cookieclickerer33 (Nov. 1, 2023 11:44:01)

mybearworld
Scratcher
1000+ posts

Chloe’s first class list extension

Interesting! How can you use that extension?
cookieclickerer33
Scratcher
1000+ posts

Chloe’s first class list extension

mybearworld wrote:

Interesting! How can you use that extension?
https://scratch.mit.edu/projects/916486596/editor/ Has a comment that has the text code
Show me what you make I’m very intrigued to see what people can do with this

It’s fully open source so it should be fine, just import it to turbowarp

My dream is to get this into the extension gallery if I expand it more

Last edited by cookieclickerer33 (Oct. 31, 2023 11:45:20)

cookieclickerer33
Scratcher
1000+ posts

Chloe’s first class list extension

Just a quick note: text strings count as a list with 1 item
cookieclickerer33
Scratcher
1000+ posts

Chloe’s first class list extension

Oops! Idk how I missed that but the comment was missing the C at the beginning of the work “class” so the extension wouldn’t load!!

It should work now that I updated the project
Clippy-Cat
Scratcher
66 posts

Chloe’s first class list extension

cookieclickerer33 wrote:

https://scratch.mit.edu/projects/916486596/editor/ Has a comment that has the text code
Show me what you make I’m very intrigued to see what people can do with this

It’s fully open source so it should be fine, just import it to turbowarp

My dream is to get this into the extension gallery if I expand it more
I believe that @mybearworld was asking for a link to a website such as GitHub. However, since you posted it as a comment within a Scratch Project, here's the code contained in there:
class ListExtension {
  constructor(runtime) {
    this.runtime = runtime;
    this.customList = []; // just to be safe this is here
  }
  getInfo() {
    return {
      id: 'listextension',
      name: 'First class lists',
      color1: '#ff0000', // Red
      color2: '#e83600', // Dark red orange
      color3: '#9e0514', // reddish brown
      blocks: [
        {
          opcode: 'listItems',
          blockType: Scratch.BlockType.REPORTER,
          text: 'list [ITEM1] and [ITEM2]',
          arguments: {
            ITEM1: {
              type: Scratch.ArgumentType.STRING,
              defaultValue: 'Item 1',
            },
            ITEM2: {
              type: Scratch.ArgumentType.STRING,
              defaultValue: 'Item 2',
            },
          },
        },
        {
          opcode: 'getItemAtIndex',
          blockType: Scratch.BlockType.REPORTER,
          text: 'item [INDEX] of [LIST]',
          arguments: {
            INDEX: {
              type: Scratch.ArgumentType.NUMBER,
              defaultValue: 1,
            },
            LIST: {
              type: Scratch.ArgumentType.BLOCK,
              defaultValue: {
                opcode: 'lists_create_with',
                type: Scratch.ArgumentType.LIST,
              },
            },
          },
        },
        {
          opcode: 'indexInList',
          blockType: Scratch.BlockType.REPORTER,
          text: 'the [FIRSTORLAST] index of [ITEM] in [LIST]',
          arguments: {
            FIRSTORLAST: {
              type: Scratch.ArgumentType.DROPDOWN,
              menu: 'firstLast',
              defaultValue: 'first',
            },
            ITEM: {
              type: Scratch.ArgumentType.STRING,
              defaultValue: 'Item',
            },
            LIST: {
              type: Scratch.ArgumentType.BLOCK,
              defaultValue: {
                opcode: 'lists_create_with',
                type: Scratch.ArgumentType.LIST,
              },
            },
          },
        },
        {
          opcode: 'indicesOf',
          blockType: Scratch.BlockType.REPORTER,
          text: 'indices of [ITEM] in [LIST]',
          arguments: {
            ITEM: {
              type: Scratch.ArgumentType.STRING,
              defaultValue: 'Item',
            },
            LIST: {
              type: Scratch.ArgumentType.BLOCK,
              defaultValue: {
                opcode: 'lists_create_with',
                type: Scratch.ArgumentType.LIST,
              },
            },
          },
        },
        {
          opcode: 'listAttribute',
          blockType: Scratch.BlockType.REPORTER,
          text: 'get [ATTRIBUTE] of [LIST]',
          arguments: {
            ATTRIBUTE: {
              type: Scratch.ArgumentType.DROPDOWN,
              menu: 'listAttributes',
              defaultValue: 'length',
            },
            LIST: {
              type: Scratch.ArgumentType.BLOCK,
              defaultValue: {
                opcode: 'lists_create_with',
                type: Scratch.ArgumentType.LIST,
              },
            },
          },
        },
        {
          opcode: 'setItemAtIndex',
          blockType: Scratch.BlockType.REPORTER,
          text: 'set item [INDEX] to [ITEM] in [LIST]',
          arguments: {
            INDEX: {
              type: Scratch.ArgumentType.NUMBER,
              defaultValue: 1,
            },
            ITEM: {
              type: Scratch.ArgumentType.STRING,
              defaultValue: 'New Item',
            },
            LIST: {
              type: Scratch.ArgumentType.BLOCK,
              defaultValue: {
                opcode: 'lists_create_with',
                type: Scratch.ArgumentType.LIST,
              },
            },
          },
        },
      ],
      menus: {
        firstLast: {
          acceptReporters: false,
          items: ['first', 'last'],
        },
        listAttributes: {
          acceptReporters: false,
          items: ['length', 'reverse'], // Add more options as needed
        },
      },
    };
  }
  listItems(args) {
    return args.ITEM1 + '\n' + args.ITEM2;
  }
  getItemAtIndex(args) {
    const index = args.INDEX;
    const list = args.LIST;
    if (list) {
      // Split the list by newline characters.
      const items = list.split('\n');
      if (index >= 1 && index <= items.length) {
        // Return the item at the specified index.
        return items[index - 1];
      }
    }
    // Return an empty string if there's no list or the index is out of bounds.
    return '';
  }
  indexInList(args) {
    const firstOrLast = args.FIRSTORLAST;
    const item = args.ITEM;
    const list = args.LIST;
    items: ['first', 'last']
    if (list) {
      // Split the list by newline characters.
      const items = list.split('\n');
      const indices = [];
      // Find all indices where the item appears.
      for (let i = 0; i < items.length; i++) {
        if (items[i] === item) {
          indices.push(i + 1); // Adding 1 to match Scratch's indexing.
        }
      }
      if (indices.length > 0) {
        if (firstOrLast === 'first') {
          return indices[0]; // Return the first index.
        } else if (firstOrLast === 'last') {
          return indices[indices.length - 1]; // Return the last index.
        }
      }
    }
    // Return an empty string if there's no list or the item is not found.
    return '';
  }
  indicesOf(args) {
    const item = args.ITEM;
    const list = args.LIST;
    if (list) {
      // Split the list by newline characters.
      const items = list.split('\n');
      const indices = [];
      // Find all indices where the item appears.
      for (let i = 0; i < items.length; i++) {
        if (items[i] === item) {
          indices.push(i + 1); // Adding 1 to match Scratch's indexing.
        }
      }
      return indices.join('\n'); // Join indices with newline characters.
    }
    // Return an empty string if there's no list.
    return '';
  }
  listAttribute(args) {
    const attribute = args.ATTRIBUTE;
    const list = args.LIST;
    if (list) {
      // Split the list by newline characters.
      const items = list.split('\n');
      if (attribute === 'length') {
        return items.length;
      } else if (attribute === 'reverse') {
        return items.reverse().join('\n'); // Reverse the list and join with newline characters.
      }
    }
    // Return an empty string if there's no list or for unsupported attributes.
    return '';
  }
  setItemAtIndex(args) {
    const index = args.INDEX;
    const newItem = args.ITEM;
    const list = args.LIST;
    if (list) {
      // Split the list by newline characters.
      const items = list.split('\n');
      if (index >= 1 && index <= items.length) {
        // Replace the item at the specified index with the new item.
        items[index - 1] = newItem;
        return items.join('\n'); // Join the modified list with newline characters.
      }
    }
    // Return the original list if there's no list or the index is out of bounds.
    return list;
  }
}
Scratch.extensions.register(new ListExtension());
The comment above it states “copy this into turbowarp!!”, I believe this is referring to when you go to Add Extension > Custom Extension within the Turbowarp editor, you should click on the “Text” tab, and paste this class into the provided textbox, you do not need to exit it out of the extension sandbox.
cookieclickerer33
Scratcher
1000+ posts

Chloe’s first class list extension

Oh my, thank you so so much, clippy!!! I didn’t know the code tab didn’t show the full thing and made it into a scroll bar!!

And yes that is what it’s referring to I should clarify that
cookieclickerer33
Scratcher
1000+ posts

Chloe’s first class list extension

I edited the original post to have the code in the code bb code tag instead of in a project comment. It’s hard to select the text in project comments anyway so this is better. I would have done this if I knew the code tag made a scroll bar and didn’t just plaster tons of text into the post
Jackfriendjoe2
Scratcher
14 posts

Chloe’s first class list extension

cookieclickerer33 wrote:

Note: all the images you see here are pictures of this extension running in scratch, no trickery!

I made a custom extension that adds first class lists, copy the code from the below area and then in turbowarp press “load from url” then “load from text” then paste it in, if you want no 1 frame delay for the blocks running you have to make the extension unsandboxxed.
class ListExtension {
constructor(runtime) {
this.runtime = runtime;
this.customList = [];
}
getInfo() {
return {
id: 'listextension',
name: 'First class lists',
color1: '#ff0000', // Red
color2: '#e83600', // Dark red orange
color3: '#9e0514', // reddish brown
blocks: [
{
opcode: 'listItems',
blockType: Scratch.BlockType.REPORTER,
text: 'list [ITEM1] and [ITEM2]',
arguments: {
ITEM1: {
type: Scratch.ArgumentType.STRING,
defaultValue: 'Item 1',
},
ITEM2: {
type: Scratch.ArgumentType.STRING,
defaultValue: 'Item 2',
},
},
},
{
opcode: 'getItemAtIndex',
blockType: Scratch.BlockType.REPORTER,
text: 'item [INDEX] of [LIST]',
arguments: {
INDEX: {
type: Scratch.ArgumentType.NUMBER,
defaultValue: 1,
},
LIST: {
type: Scratch.ArgumentType.BLOCK,
defaultValue: {
opcode: 'lists_create_with',
type: Scratch.ArgumentType.LIST,
},
},
},
},
{
opcode: 'indexInList',
blockType: Scratch.BlockType.REPORTER,
text: 'the [FIRSTORLAST] index of [ITEM] in [LIST]',
arguments: {
FIRSTORLAST: {
type: Scratch.ArgumentType.DROPDOWN,
menu: 'firstLast',
defaultValue: 'first',
},
ITEM: {
type: Scratch.ArgumentType.STRING,
defaultValue: 'Item',
},
LIST: {
type: Scratch.ArgumentType.BLOCK,
defaultValue: {
opcode: 'lists_create_with',
type: Scratch.ArgumentType.LIST,
},
},
},
},
{
opcode: 'indicesOf',
blockType: Scratch.BlockType.REPORTER,
text: 'indices of [ITEM] in [LIST]',
arguments: {
ITEM: {
type: Scratch.ArgumentType.STRING,
defaultValue: 'Item',
},
LIST: {
type: Scratch.ArgumentType.BLOCK,
defaultValue: {
opcode: 'lists_create_with',
type: Scratch.ArgumentType.LIST,
},
},
},
},
{
opcode: 'listAttribute',
blockType: Scratch.BlockType.REPORTER,
text: 'get [ATTRIBUTE] of [LIST]',
arguments: {
ATTRIBUTE: {
type: Scratch.ArgumentType.DROPDOWN,
menu: 'listAttributes',
defaultValue: 'length',
},
LIST: {
type: Scratch.ArgumentType.BLOCK,
defaultValue: {
opcode: 'lists_create_with',
type: Scratch.ArgumentType.LIST,
},
},
},
},
{
opcode: 'setItemAtIndex',
blockType: Scratch.BlockType.REPORTER,
text: 'set item [INDEX] to [ITEM] in [LIST]',
arguments: {
INDEX: {
type: Scratch.ArgumentType.NUMBER,
defaultValue: 1,
},
ITEM: {
type: Scratch.ArgumentType.STRING,
defaultValue: 'New Item',
},
LIST: {
type: Scratch.ArgumentType.BLOCK,
defaultValue: {
opcode: 'lists_create_with',
type: Scratch.ArgumentType.LIST,
},
},
},
},
],
menus: {
firstLast: {
acceptReporters: false,
items: ['first', 'last'],
},
listAttributes: {
acceptReporters: false,
items: ['length', 'reverse'], // Add more options as needed
},
},
};
}
listItems(args) {
return args.ITEM1 + '\n' + args.ITEM2;
}
getItemAtIndex(args) {
const index = args.INDEX;
const list = args.LIST;
if (list) {
// Split the list by newline characters.
const items = list.split('\n');
if (index >= 1 && index <= items.length) {
// Return the item at the specified index.
return items[index - 1];
}
}
// Return an empty string if there's no list or the index is out of bounds.
return '';
}
indexInList(args) {
const firstOrLast = args.FIRSTORLAST;
const item = args.ITEM;
const list = args.LIST;
items: ['first', 'last']
if (list) {
// Split the list by newline characters.
const items = list.split('\n');
const indices = [];
// Find all indices where the item appears.
for (let i = 0; i < items.length; i++) {
if (items[i] === item) {
indices.push(i + 1); // Adding 1 to match Scratch's indexing.
}
}
if (indices.length > 0) {
if (firstOrLast === 'first') {
return indices[0]; // Return the first index.
} else if (firstOrLast === 'last') {
return indices[indices.length - 1]; // Return the last index.
}
}
}
// Return an empty string if there's no list or the item is not found.
return '';
}
indicesOf(args) {
const item = args.ITEM;
const list = args.LIST;
if (list) {
// Split the list by newline characters.
const items = list.split('\n');
const indices = [];
// Find all indices where the item appears.
for (let i = 0; i < items.length; i++) {
if (items[i] === item) {
indices.push(i + 1); // Adding 1 to match Scratch's indexing.
}
}
return indices.join('\n'); // Join indices with newline characters.
}
// Return an empty string if there's no list.
return '';
}
listAttribute(args) {
const attribute = args.ATTRIBUTE;
const list = args.LIST;
if (list) {
// Split the list by newline characters.
const items = list.split('\n');
if (attribute === 'length') {
return items.length;
} else if (attribute === 'reverse') {
return items.reverse().join('\n'); // Reverse the list and join with newline characters.
}
}
// Return an empty string if there's no list or for unsupported attributes.
return '';
}
setItemAtIndex(args) {
const index = args.INDEX;
const newItem = args.ITEM;
const list = args.LIST;
if (list) {
// Split the list by newline characters.
const items = list.split('\n');
if (index >= 1 && index <= items.length) {
// Replace the item at the specified index with the new item.
items[index - 1] = newItem;
return items.join('\n'); // Join the modified list with newline characters.
}
}
// Return the original list if there's no list or the index is out of bounds.
return list;
}
}
Scratch.extensions.register(new ListExtension());
Here’s the rundown of all the blocks you see here:

The
(list [a] and [b] :: list)
Block returns a first class list with the items specified, if you want more than 2 items do
(list [a] and (list [b] and [c] :: list) :: list)
This returns a list containing a,b,c
(item (1) of (\ \ \:: #590101):: list)
Returns the item number specified of the first class list of the second input
(The [first v] index of [thing] in (\ \ \:: #590101)::list)
(The [last v] index of [thing] in (\ \ \:: #590101)::list)
Returns the item number of the first or last item that is the same as the provided string
For example

And

The
(Indices of [thing] in (\ \ \:: #590101):: list)
Block returns a list of all the item numbers that match the provided string, as an example:


The
(Set item (1) to [thing] in (\ \ \:: #590101):: list)
Block works just like
replace item ( v) of [list v] with [thing]
But with first class lists

And finally there’s
(Get [length v] of (\ \ \:: #590101) :: list)
(Get [reverse v] of (\ \ \:: #590101)::list)
The “length” option returns the amount of items in the list, and the “reverse” option returns the list with the item numbers of each item swapped (so the first item becomes the last, the last becomes the first etc.)

You can set these to variables just fine and they display properly, there’s also no trickery here, the system just works with no caviots


I hope you all like this!
Cool extension, awesome when loaded into turbowarp and messed around with, sadly i dont know javascript but making these seems fun!
mybearworld
Scratcher
1000+ posts

Chloe’s first class list extension

Clippy-Cat wrote:

(#6)
I believe that @mybearworld was asking for a link to a website such as GitHub. However, since you posted it as a comment within a Scratch Project, here's the code contained in there:
I was just asking for a way to try it out, and got it! This is a pretty cool extension. I have a suggestion - maybe you could use a proper input field? With addons, this currently looks like this:
god286
Scratcher
1000+ posts

Chloe’s first class list extension

cookieclickerer33 wrote:

I edited the original post to have the code in the code bb code tag instead of in a project comment. It’s hard to select the text in project comments anyway so this is better. I would have done this if I knew the code tag made a scroll bar and didn’t just plaster tons of text into the post
You could even minify the code into one line using https://jsminify.org/
DifferentDance8
Scratcher
1000+ posts

Chloe’s first class list extension

The extension doesn't work when doing what Clippy-Cat said, and looking in the console didn't show me any errors.
cookieclickerer33
Scratcher
1000+ posts

Chloe’s first class list extension

mybearworld wrote:

Clippy-Cat wrote:

(#6)
I believe that @mybearworld was asking for a link to a website such as GitHub. However, since you posted it as a comment within a Scratch Project, here's the code contained in there:
I was just asking for a way to try it out, and got it! This is a pretty cool extension. I have a suggestion - maybe you could use a proper input field? With addons, this currently looks like this:
Well you aren’t able to type inside the list input slots, otherwise it would be very strange and it wouldn’t be clear what’s a list and what isn’t

To put it simply that input slot is the Boolean input slot but shaped like a reporter (or if you know blockly, it’s actually a circular drop-down slot with no drop-down added into it)

This makes it clear what needs to go in what slots like how in snap there’s a list input.
cookieclickerer33
Scratcher
1000+ posts

Chloe’s first class list extension

DifferentDance8 wrote:

The extension doesn't work when doing what Clippy-Cat said, and looking in the console didn't show me any errors.
You can only import 1 url extension at a time in turbowarp (from what I can tell)
If you already have a url extension imported (or tried an import and it failed) then it won’t let you import any others

Try again using the code of the fourm post btw if you used the comment in the project, it worked fine for me

Last edited by cookieclickerer33 (Nov. 2, 2023 11:28:37)

Powered by DjangoBB