Discuss Scratch

cookieclickerer33
Scratcher
1000+ posts

First class list extension (new: Json update!) (now released!!)

Here’s my new first class list extension!

https://scratch.mit.edu/discuss/post/7762693/


If you didn’t see the old legacy version here are the things it does!

It adds first class list support in a simple to understand, easy to read, and mostly unambiguous, way that also meets scratch’s design goals (what other extensions fail to do)

this doesn’t use json arrays to display the text either but instead a semi complex system that I won’t get into to render it like you see below!

The original version of this was buggy, slow, and broke in a few areas.
The old version had the following blocks just for future reference


The changes
Changes to the old blocks in the legacy version include:

Full rewrite of all extension code

Default permaiter names have been changed
Removed errors in place of either returning nothing or returning one of the inputs
“Indices of” and “the first/last index of” blocks have been merged into “first/last/every index of”
“List A and B” has been renamed to “list A with B” to make the grammar correct
“Get (thing) of (list)” has been renamed to just “(thing) of (list)” (more changes to it will be covered later on)

The new stuff!

Here’s the blocks in the original version (NOT the legacy version)


Here’s what they do!

“List (A) with (B)” creates a list with the items, like “join” put another one of these blocks into the inputs to add another item, combine 2 lists, or add something in front

“Item (num) of (list)” works the normal scratch block

“Insert (A) at (num) in (list)” works the normal scratch block

“Set item (num) to (A) in (list)” replaces the item at the number given with the thing input

“(Type) index of (A) in (list)” if the “first” option is selected then it will return the item number where the text in the A input appears. If the “last” option is selected it will return the item number of the last time it appears. If the “every” option is selected then the block will return a list of every item number where the text appears. (This was the previous function of the “indices of” block before being merged)

“Split (A) by (B)” returns a list of the text (A) being split at the splitter (B) (useful for converting scratch lists into first class ones via their reporter)

“Join (list) by (A)” returns the list provided as text being split by the text (A)

“Is (A) a list?” Returns true if the input (A) is a first class list

there’s another block that has its own section, and deserves it

the “(thing) of (list)” block
Here are the drop-down options available in this block


And I’ll explain all of them now.

Misc:
Length: get the ammount of items in the list
Reverse: get the list with the order of all the items being flipped (first item becomes the last, last becomes the first, etc)
Last: returns the item at the end of the list
Random: returns an item in the list picked randomly
Array: returns the list as a json array (for compatibility with other extensions)

Math: (these only work if the list is made up of numbers)
Smallest: returns the smallest item in the list
Biggest: returns the largest item in the list
Sum: returns the value of all items in the list added together
Adverage: the value of all items in the list divided by the length of the list

Sorting:
Low to high: orders the items in the list ordered from numbers smallest to biggest
A to Z: sorts the list alphabetically

the v2 update:
The v2 update added the following blocks:

Their functions are as follows:

“Items from (A) to (B) of (list)” returns a list of the items between the first input (A) and the second (B).
{sort of requested by ajskateboarder, was already complete when requested}

“Delete (num) of (list)” removes the item at the number given, like the normal scratch block

(The 2 blocks above where added in a smaller v0.9 update but are considered part of 2.0)

“give: (value) name of: (key)” stores a value under a name as part of a list, denoted by an = sign

(Thanks to some Unicode magic list items that have an equals sign in them will not break this system. Go wild!)

“item named (name) in (list)” gets the value a via a name given by the previous block

“all (names/values) of (list)” returns a normal list of all the item names/values of a named list


Last edited by cookieclickerer33 (Jan. 23, 2024 18:22:17)

ajskateboarder
Scratcher
1000+ posts

First class list extension (new: Json update!) (now released!!)

Cooley!!!! It would also be cool to have a way to slice a list sometime in the future, like you can in Python:
>>> x = [1, 2, 3, 4, 5]
>>> x[0:2]
[1, 2, 3]
>>> x[:2]
[1, 2, 3]
>>> x[-1:-2]
[3, 4, 5]
cookieclickerer33
Scratcher
1000+ posts

First class list extension (new: Json update!) (now released!!)

V0.9: the “while bugfixing I realized I should probobly add these” update.

Added “delete (num) of (list)” block
Added “items (a) to (b) of (list)” block
cookieclickerer33
Scratcher
1000+ posts

First class list extension (new: Json update!) (now released!!)

ajskateboarder wrote:

Cooley!!!! It would also be cool to have a way to slice a list sometime in the future, like you can in Python:
>>> x = [1, 2, 3, 4, 5]
>>> x[0:2]
[1, 2, 3]
>>> x[:2]
[1, 2, 3]
>>> x[-1:-2]
[3, 4, 5]
I believe I added this by coincidence in 0.9
cookieclickerer33
Scratcher
1000+ posts

First class list extension (new: Json update!) (now released!!)

A change is happening

This version is now just called “fist class lists” instead of “first class lists v2” the old version of this extension will now be referred to as “legacy first class lists”

This is to make way for an upcoming v3 update that I don’t wanna spoil and also will mark the release of the extension
cookieclickerer33
Scratcher
1000+ posts

First class list extension (new: Json update!) (now released!!)

V2: the “Jason?!” Update

Added “give: (value) name of: (key)” block to store a value under a name as part of a list, denoted by an = sign
(don’t worry it’s surrounded by special Unicode characters so the = sign is purely visual and items that have one will not interfere with the system)

Added “item named (name) in (list)” block to get the value a via a name given by the previous block

Added “all (names/values) of (list)” block that returns a normal list of all the item names/values of a named list



cookieclickerer33
Scratcher
1000+ posts

First class list extension (new: Json update!) (now released!!)

I can’t think of a better name for a list that has values with names. I want to get rid of anything that refrences keys or json as that’s not very scratch like

If you think about it, the name “key” doesn’t make any sense if you don’t know it’s being discussed in a programming context. Name is just better in general so I think I’m gonna go with “named list” but that still needs some working on


Also I’ll add your ideas 100%
cookieclickerer33
Scratcher
1000+ posts

First class list extension (new: Json update!) (now released!!)

It’s out!

This should function without and with the sandbox, but it is recommended you run it without the sandbox as otherwise there is a forced delay of 1 frame between each block report due to scratch stuff
If for whatever reason you don’t trust me then run it sandboxed, the source code is literallly right here tho so I don’t know why that would be
//created by cookieclickerer33 aka Chloe 
//internal name, firstClistvthree, v1 was the old version now called legacy first class //lists, v2 (now first class lists) was this extension without the json blocks, delete item, //or items a to b of list block.
(function(Scratch) {
const blocks = [];
const vars = {};
const menus = {};



class Extension {
getInfo() {
return {
"id": "firsclistvthree",
"name": "First class lists",
"color1": "#e22400",
"blocks": blocks,
"menus": menus,
}
}
}

var List, Array2, Thing, i;

// old version Converts a first class list input into a JSON array
function ListToArr(List) {
const localVars = {};
return List.split("\n");
}

// old version Converts a JSON array into a first class list
function ArrToList(Array2) {
const localVars = {};
return Array2.join("\n");
}

// old version returns if the input is a first class list or not
function Is_input_a_list(Thing) {
const localVars = {};
return !(null == Thing || '' == Thing);
}

function mathMean(myList) {
return myList.reduce(function(x, y) {return x + y;}, 0) / myList.length;
}

function listsGetSortCompare(type, direction) {
var compareFuncs = {
'NUMERIC': function(a, b) {
return Number(a) - Number(b); },
'TEXT': function(a, b) {
return String(a) > String(b) ? 1 : -1; },
'IGNORE_CASE': function(a, b) {
return String(a).toLowerCase() > String(b).toLowerCase() ? 1 : -1; },
};
var compare = compareFuncs[type];
return function(a, b) { return compare(a, b) * direction; };
}

function mathRandomList(list) {
var x = Math.floor(Math.random() * list.length);
return list[x];
}

// the splitter used to separate keys and values
function Json_splitter() {
const localVars = {};
return ' = ';
}

function textReplace(haystack, needle, replacement) {
needle = needle.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1')
.replace(/\x08/g, '\\x08');
return haystack.replace(new RegExp(needle, 'g'), replacement);
}

// used when the input is not a list for blocks that need it
function Empty() {
const localVars = {};
return "\n";
}


// Converts a first class list input into a JSON array
function ListToArr(List) {
const localVars = {};
return List.split("\n");
}
// Converts a JSON array into a first class list
function ArrToList(Array2) {
const localVars = {};
return Array2.join("\n");
}
// returns if the input is a first class list or not
function Is_input_a_list(Thing) {
const localVars = {};
return !(null == Thing || '' == Thing);
}

blocks.push({
opcode: "firsclistvthree_Block_Createlist",
blockType: Scratch.BlockType.REPORTER,
text: "list [A] with [B]",
arguments: {
"A": {
type: Scratch.ArgumentType.STRING,
defaultValue: `A`
},
"B": {
type: Scratch.ArgumentType.STRING,
defaultValue: `B`
},

},
disableMonitor: true
});
Extension.prototype["firsclistvthree_Block_Createlist"] = function(args, util) {
const localVars = {};
return [args["A"],"\n",args["B"]].join('');
};


blocks.push({
opcode: "firsclistvthree_Block_Itemof",
blockType: Scratch.BlockType.REPORTER,
text: "Item [N] of [L]",
arguments: {
"N": {
type: Scratch.ArgumentType.STRING,
defaultValue: `1`
},
"L": {
type: Scratch.ArgumentType.empty,
defaultValue: ``
},

},
disableMonitor: true
});
Extension.prototype["firsclistvthree_Block_Itemof"] = function(args, util) {
const localVars = {};
if (Is_input_a_list(args["L"])) {
return ListToArr(args["L"])[(args["N"] - 1)];} else {
return Empty();}

};


blocks.push({
opcode: "firsclistvthree_Block_delete",
blockType: Scratch.BlockType.REPORTER,
text: "delete [N] of [L]",
arguments: {
"N": {
type: Scratch.ArgumentType.NUMBER,
defaultValue: `1`
},
"L": {
type: Scratch.ArgumentType.empty,
defaultValue: ``
},

},
disableMonitor: true
});
Extension.prototype["firsclistvthree_Block_delete"] = function(args, util) {
const localVars = {};
if (Is_input_a_list(args["L"])) {
localVars['Delout'] = (ListToArr(args["L"]));
localVars['Delout'].splice((args["N"] - 1), 1);
return ArrToList(localVars['Delout']);} else {
return Empty();}

};


blocks.push({
opcode: "firsclistvthree_Block_insert",
blockType: Scratch.BlockType.REPORTER,
text: "insert [A] at [N] of [L]",
arguments: {
"A": {
type: Scratch.ArgumentType.STRING,
defaultValue: `Thing`
},
"N": {
type: Scratch.ArgumentType.NUMBER,
defaultValue: `1`
},
"L": {
type: Scratch.ArgumentType.empty,
defaultValue: ``
},

},
disableMonitor: true
});
Extension.prototype["firsclistvthree_Block_insert"] = function(args, util) {
const localVars = {};
if (Is_input_a_list(args["L"])) {
localVars['Insertout'] = (ListToArr(args["L"]));
localVars['Insertout'].splice((args["N"] - 1), 0, args["A"]);
return ArrToList(localVars['Insertout']);} else {
return args["A"];}

};


blocks.push({
opcode: "firsclistvthree_Block_replace",
blockType: Scratch.BlockType.REPORTER,
text: "set item [N] to [A] in [L]",
arguments: {
"N": {
type: Scratch.ArgumentType.NUMBER,
defaultValue: `1`
},
"A": {
type: Scratch.ArgumentType.STRING,
defaultValue: `Thing`
},
"L": {
type: Scratch.ArgumentType.empty,
defaultValue: ``
},

},
disableMonitor: true
});
Extension.prototype["firsclistvthree_Block_replace"] = function(args, util) {
const localVars = {};
if (Is_input_a_list(args["L"])) {
localVars['setout'] = (ListToArr(args["L"]));
localVars['setout'][(args["N"] - 1)] = args["A"];
return ArrToList(localVars['setout']);} else {
return args["A"];}

};


blocks.push({
opcode: "firsclistvthree_Block_Indexof",
blockType: Scratch.BlockType.REPORTER,
text: "[M] index of [A] in [L]",
arguments: {
"M": {
type: Scratch.ArgumentType.STRING,
menu: "firsclistvthree_customMenu_IndexMenu",
},
"A": {
type: Scratch.ArgumentType.STRING,
defaultValue: `Thing`
},
"L": {
type: Scratch.ArgumentType.empty,
defaultValue: ``
},

},
disableMonitor: true
});
Extension.prototype["firsclistvthree_Block_Indexof"] = function(args, util) {
const localVars = {};
if (Is_input_a_list(args["L"])) {
if (args["M"] == 'first') {
return ListToArr(args["L"]).indexOf(args["A"]) + 1;} else if (args["M"] == 'last') {
return ListToArr(args["L"]).lastIndexOf(args["A"]) + 1;} else {
localVars['out'] = [];
localVars['list'] = (ListToArr(args["L"]));
var repeat_end = ListToArr(args["L"]).lastIndexOf(args["A"]) + 1;
for (var count = 0; count < repeat_end; count++) {
if (0 != localVars['list'].indexOf(args["A"]) + 1) {
localVars['out'].push(localVars['list'].indexOf(args["A"]) + 1);
localVars['list'].splice(((localVars['list'].indexOf(args["A"]) + 1) - 1), 1);
}
}
return ArrToList(localVars['out']);}
} else {
return Empty();}

};


blocks.push({
opcode: "firsclistvthree_Block_Listattr",
blockType: Scratch.BlockType.REPORTER,
text: "[M] of [L]",
arguments: {
"L": {
type: Scratch.ArgumentType.empty,
defaultValue: ``
},
"M": {
type: Scratch.ArgumentType.STRING,
menu: "firsclistvthree_customMenu_Listatrm",
},

},
disableMonitor: true
});
Extension.prototype["firsclistvthree_Block_Listattr"] = function(args, util) {
const localVars = {};
if (Is_input_a_list(args["L"])) {
if (args["M"] == 'length') {
return ListToArr(args["L"]).length;} else if (args["M"] == 'reverse') {
return ArrToList(ListToArr(args["L"]).slice().reverse());} else if (args["M"] == 'last') {
return ArrToList(ListToArr(args["L"]).slice(-1)[0]);} else if (args["M"] == 'smallest') {
return Math.min.apply(null, ListToArr(args["L"]));} else if (args["M"] == 'biggest') {
return Math.max.apply(null, ListToArr(args["L"]));} else if (args["M"] == 'sum') {
return ListToArr(args["L"]).reduce(function(x, y) {return x + y;}, 0);} else if (args["M"] == 'adverage') {
return mathMean(ListToArr(args["L"]));} else if (args["M"] == 'low to high') {
return ArrToList(ListToArr(args["L"]).slice().sort(listsGetSortCompare("NUMERIC", 1)));} else if (args["M"] == 'A to Z') {
return ArrToList(ListToArr(args["L"]).slice().sort(listsGetSortCompare("IGNORE_CASE", 1)));} else if (args["M"] == 'array') {
return ListToArr(args["L"]);} else {
return mathRandomList(ListToArr(args["L"]));}
} else {
return Empty();}

};

menus["firsclistvthree_customMenu_IndexMenu"] = {
acceptReporters: false,
items: ['first', 'last', 'every'],
};
menus["firsclistvthree_customMenu_Listatrm"] = {
acceptReporters: false,
items: ['length', 'reverse', 'last', 'smallest', 'biggest', 'sum', 'adverage', 'low to high', 'A to Z', 'random', 'array'],
};
// get json splitter
// get json splitter
function Json_splitter() {
const localVars = {};
return ' = ';
}

blocks.push({
opcode: "firsclistvthree_Block_Split",
blockType: Scratch.BlockType.REPORTER,
text: "split [A] by [B]",
arguments: {
"A": {
type: Scratch.ArgumentType.STRING,
defaultValue: `A-B-C`
},
"B": {
type: Scratch.ArgumentType.STRING,
defaultValue: `-`
},

},
disableMonitor: true
});
Extension.prototype["firsclistvthree_Block_Split"] = function(args, util) {
const localVars = {};
return textReplace(args["A"], args["B"], "\n");
};

//return empty if the list is empty
function Empty() {
const localVars = {};
return "\n";
}

blocks.push({
opcode: "firsclistvthree_Block_Listjoin",
blockType: Scratch.BlockType.REPORTER,
text: "join [L] by [A]",
arguments: {
"L": {
type: Scratch.ArgumentType.empty,
defaultValue: ``
},
"A": {
type: Scratch.ArgumentType.STRING,
defaultValue: `-`
},

},
disableMonitor: true
});
Extension.prototype["firsclistvthree_Block_Listjoin"] = function(args, util) {
const localVars = {};
if (Is_input_a_list(args["L"])) {
return args["L"].split("\n").join(args["A"]);} else {
return args["A"];}

};


blocks.push({
opcode: "firsclistvthree_Block_sublist",
blockType: Scratch.BlockType.REPORTER,
text: "items from [A] to [B] of [L]",
arguments: {
"A": {
type: Scratch.ArgumentType.NUMBER,
defaultValue: `2`
},
"B": {
type: Scratch.ArgumentType.NUMBER,
defaultValue: `4`
},
"L": {
type: Scratch.ArgumentType.empty,
defaultValue: ``
},

},
disableMonitor: true
});
Extension.prototype["firsclistvthree_Block_sublist"] = function(args, util) {
const localVars = {};
if (Is_input_a_list(args["L"])) {
return ArrToList(ListToArr(args["L"]).slice((args["A"] - 1), args["B"]));} else {
return Empty();}

};


blocks.push({
opcode: "firsclistvthree_Block_Islist",
blockType: Scratch.BlockType.BOOLEAN,
text: "is [A] a list?",
arguments: {
"A": {
type: Scratch.ArgumentType.STRING,
defaultValue: `thing`
},

},
disableMonitor: true
});
Extension.prototype["firsclistvthree_Block_Islist"] = function(args, util) {
const localVars = {};
return 0 != args["A"].indexOf("\n") + 1;
};


blocks.push({
opcode: "firsclistvthree_Block_Keyval",
blockType: Scratch.BlockType.REPORTER,
text: "give: [V] name of: [K]",
arguments: {
"V": {
type: Scratch.ArgumentType.STRING,
defaultValue: `value`
},
"K": {
type: Scratch.ArgumentType.STRING,
defaultValue: `name`
},

},
disableMonitor: true
});
Extension.prototype["firsclistvthree_Block_Keyval"] = function(args, util) {
const localVars = {};
return [args["K"],Json_splitter(),args["V"]].join('');
};


blocks.push({
opcode: "firsclistvthree_Block_Jsonget",
blockType: Scratch.BlockType.REPORTER,
text: "item named [A] in [L]",
arguments: {
"A": {
type: Scratch.ArgumentType.STRING,
defaultValue: `name`
},
"L": {
type: Scratch.ArgumentType.empty,
defaultValue: ``
},

},
disableMonitor: true
});
Extension.prototype["firsclistvthree_Block_Jsonget"] = function(args, util) {
const localVars = {};
if (Is_input_a_list(args["L"])) {
localVars['Json'] = {};
var i_list = ListToArr(args["L"]);
for (var i_index in i_list) {
i = i_list[i_index];
localVars['Json'] = (() => {
const temp = structuredClone(localVars['Json']);
temp[(i.split(Json_splitter())[0])] = (i.split(Json_splitter()).slice(-1)[0]);
return temp;
})();
}
return localVars['Json'][args["A"]];} else {
return Empty();}

};

menus["firsclistvthree_customMenu_Keyorval"] = {
acceptReporters: false,
items: ['names', 'values'],
};

blocks.push({
opcode: "firsclistvthree_Block_allthings",
blockType: Scratch.BlockType.REPORTER,
text: "all [M] of [L]",
arguments: {
"L": {
type: Scratch.ArgumentType.empty,
defaultValue: ``
},
"M": {
type: Scratch.ArgumentType.STRING,
menu: "firsclistvthree_customMenu_Keyorval",
},

},
disableMonitor: true
});
Extension.prototype["firsclistvthree_Block_allthings"] = function(args, util) {
const localVars = {};
if (Is_input_a_list(args["L"])) {
localVars['Json'] = {};
var i_list2 = ListToArr(args["L"]);
for (var i_index2 in i_list2) {
i = i_list2[i_index2];
localVars['Json'] = (() => {
const temp = structuredClone(localVars['Json']);
temp[(i.split(Json_splitter())[0])] = (i.split(Json_splitter())[0]);
return temp;
})();
}
if (args["M"] == 'values') {
return ArrToList(Object.keys(localVars['Json']));} else {
return ArrToList(Object.values(localVars['Json']));}
} else {
return Empty();}

};



Scratch.extensions.register(new Extension());
})(Scratch);
Copy paste this into turbowarp or any other scratch mod that supports loading extensions from text.
a url version may come soon!

Last edited by cookieclickerer33 (Jan. 23, 2024 18:28:49)

INSERT-USER_NAME
Scratcher
1000+ posts

First class list extension (new: Json update!) (now released!!)

(list [A] with (list [B] with [C]))
That would return a list with item one as A, and item two being a list containing the items B and C

I have no idea how to rename it so there isn't confusion like that, but I felt like pointing it out for some odd reason.
cookieclickerer33
Scratcher
1000+ posts

First class list extension (new: Json update!) (now released!!)

INSERT-USER_NAME wrote:

(list [A] with (list [B] with [C]))
That would return a list with item one as A, and item two being a list containing the items B and C

I have no idea how to rename it so there isn't confusion like that, but I felt like pointing it out for some odd reason.
I know I use snap all the time that’s why I wanted to make this, however there’s a biggg issue with this.

1: that would mean there’s no way to make a list that’s more than 2 items long as scratch doesn’t have vardradics
2: to get the same effect you could use a scratch list that has the items as first class lists
3: you could also use the split block to do this
4: there would be no way to render it

Last edited by cookieclickerer33 (Jan. 24, 2024 12:23:29)

cookieclickerer33
Scratcher
1000+ posts

First class list extension (new: Json update!) (now released!!)

From now on updates will be released as a seperate extension as I don’t really know what to add to the main extension that wouldn’t just clutter things

Like a dedicated atan2 block wouldn’t fit with the current one and should be it’s own thing


Still debating wether or not to call it atan2 or direction, calling it direction makes more sense and makes it more obvious what the block does. But calling it atan2 is correct as well as teaching them for future extensions, but also they might not realize what atan2 does

Last edited by cookieclickerer33 (Jan. 24, 2024 12:39:41)

cookieclickerer33
Scratcher
1000+ posts

First class list extension (new: Json update!) (now released!!)

I think I need a better/shorter name because “first class lists” is close to hitting the extension name limit
cookieclickerer33
Scratcher
1000+ posts

First class list extension (new: Json update!) (now released!!)

Maybe I will add 1 more block being a way to create a named list from 2 normal lists but I plan on making a seperate extension with expanded json features
Wowfunhappy
Scratcher
27 posts

First class list extension (new: Json update!) (now released!!)

Does the `item _ of _` block work, or am I doing something wrong? Just was testing for a few minutes: in the following code, pressing the up arrow key makes the sprite say “undefined”. (The down arrow key results in “bananas” as expected).

Screenshot:
https://i.ibb.co/25yKqfv/Screen-Shot-2024-01-27-at-8-24-10-AM.png

.sb3 project:
https://send.portailpro.net/download/dd25f7ddeccbbfc5/#9-z_cDqWoApS47n8Mwt08A

Edit: Oh, I see what is happening! The first class list extension does not consider normal Scratch lists to be lists. You need to make a “first class lists” list via a block such as `list _ with _` and then i will work. Is this a bug or expected behavior?

For what it's worth, I'm using the extension in Turbowarp without the sandbox.

—-

On a separate note, I really wish the list inputs were dropdown, like in the original list blocks—but oval shaped so that list reporters could be dropped on top.

Last edited by Wowfunhappy (Jan. 27, 2024 13:33:40)

gilbert_given_189
Scratcher
1000+ posts

First class list extension (new: Json update!) (now released!!)

Nice!

My eyes is screaming cons from the way you make the list, but it's not.
cookieclickerer33
Scratcher
1000+ posts

First class list extension (new: Json update!) (now released!!)

Wowfunhappy wrote:

Does the `item _ of _` block work, or am I doing something wrong? Just was testing for a few minutes: in the following code, pressing the up arrow key makes the sprite say “undefined”. (The down arrow key results in “bananas” as expected).

Screenshot:
https://i.ibb.co/25yKqfv/Screen-Shot-2024-01-27-at-8-24-10-AM.png

.sb3 project:
https://send.portailpro.net/download/dd25f7ddeccbbfc5/#9-z_cDqWoApS47n8Mwt08A

Edit: Oh, I see what is happening! The first class list extension does not consider normal Scratch lists to be lists. You need to make a “first class lists” list via a block such as `list _ with _` and then i will work. Is this a bug or expected behavior?

For what it's worth, I'm using the extension in Turbowarp without the sandbox.

—-

On a separate note, I really wish the list inputs were dropdown, like in the original list blocks—but oval shaped so that list reporters could be dropped on top.
scratch lists return an incosistant thing and this isnt ment to use scratch lists as scratch lists arent first class
scratch list type inputs are hard coded to be uninsertable as well so that isnt a possibility.
you shouldnt need to use scratch lists at all as this outclasses them

Last edited by cookieclickerer33 (Jan. 27, 2024 16:46:04)

cookieclickerer33
Scratcher
1000+ posts

First class list extension (new: Json update!) (now released!!)

basically, the list reporter for a scratch list just returns every item in the list joined by a space. if you want to make a first class list from that you would use the split block like so
(split (list reporter::list) by [(space)]::list)
this isnt a vinilla feature because
1: list inputs are hard coded to be uninsertable
2: they arent ment to be compatable, these are intended to outclass scratch lists
3: if an item in the list contains a space then it will act as 2 items (even in normal scratch)

this is mentioned in the topic post

Last edited by cookieclickerer33 (Jan. 27, 2024 16:57:57)

cookieclickerer33
Scratcher
1000+ posts

First class list extension (new: Json update!) (now released!!)

again, running without sandbox is recommended as otherwise theres a 1 frame delay between blocks running. this causes tons of lag when used in custom blocks

Powered by DjangoBB