Discuss Scratch

EPIC_SLAVER
Scratcher
13 posts

How do I make a cloud list?

So I am trying to make a admin adder button but I don't know how to make cloud lists.
If you want admin comment your username
Heres the game: https://scratch.mit.edu/projects/948051805/

Malicondi
Scratcher
1000+ posts

How do I make a cloud list?

here comes another essay…

DISCLAIMER: DO NOT QUOTE ENTIRE POST

Making cloud lists are pretty complex, but i'll explain how to make one here. If you want case-sensitivity for your cloud list, that's more complicated since scratch sucks and “a” == “A” and i'll only explain it if you want me to. But for simplicity, I'll be using non-case-sensitive.

Section I: Cloud variables and Join
Ignore if you know about cloud variables, skip to section II.

To start out a cloud list, you first will need cloud variables, like this:
(☁ foo)
You can create a cloud variable if you're a Scratcher, and by clicking “create a new variable” and checking the “cloud variables” tickbox when creating the variable. It will give you an alert about its limitations that I will explain below

cloud variables are the base of cloud lists, because well they're cloud. Cloud variables can only store up to 256 characters, and we can only create 10 cloud variables, and of which ALL of the characters have to be a number, with a few exceptions.

The exceptions are “-” and “.”, where “-” can only be at the very beginning of the cloud variable, and “.” can only be inside of the cloud variable once at any point.

Because of these limitations, we must use encoding and decoding to send data and in this case “list items” to the project, over the server. If you don't know what encoding and decoding is, I recommend watching this video by griffpatch, as he explains it quite well.

The join block is another very essential block, that is required for encoding. The join block joins together, or “Concatenates” 2 values together. Here are some examples:
(join [hello] [world]) // returns "helloworld"
set [variable v] to [abc] // works with variables
(join (variable) [def]) // returns "abcdef", because the variable's value is abc.
(join [hi ] (join [there] [!])) // nested join blocks, this returns "hi there!"
You're going to see this block, and the
(letter () of ())
block a lot.

Section II: Encoding
Where the real code starts
Make sure every custom block is “run without screen refresh” or this will be slow.

Disclaimer: when making new cloud variables set to blank or it will break.
set [cloud 1 ☁ v] to ()
As stated in Section I, because of these limitations we will have to encode and decode data in numbers to send over the cloud. There are a couple ways to do so, but i'll be using a way I prefer here, using lists with every character and number, that will be used.
First, create a custom blocks and a variable and a list, named anything, I prefer making all my variables “for this sprite only” unless I state not to.
(i) //short for index
(characters ::list)
define setup list
We can easily create a list with every character and number, like this:
define setup list
delete all of [characters v] ::list
repeat (9)
add () to [characters v]
end
set [i v] to (0)
repeat (38)
change [i v] by (1)
add (letter (i) of [abcdefghijklmnopqrstuvwxyz1234567890-_]) to [characters v]
If you want more characters, just change the repeat by how many extra characters you're adding, and add them to the (letter() of() block, for example, if you wanted to add ^, then you would change repeat to 39 and the letter block to this:
(letter (i) of [abcdefghijklmnopqrstuvwxyz1234567890-_^])
Why did I add 9 blank values?
9 blank values are added to prevent anything from being encoded into 1 letter numbers, which will break decoding later on, and solve this issue, specifically for items with only numbers.

What is this list for?
This is what I'm about to cover, the list is used to convert characters into numbers using the
(item # of () in [ v] ::list) 
block. This block returns the item number of an item inside of a list, which we can use to convert every character into a number.

To do this, we will create a new block, and a new variable:
(encoded) // holding encoded numbers
define encode (val) to cloud
set [encoded v] to ()
if <(length of (val)) > (9)> then
set [encoded v] to (join (join (encoded) (0)) (length of (val)))
else
set [encoded v] to (join (encoded) (length of (val))
end
set [i v] to (1)// im back :)
repeat (length of (val))
set [encoded v] to (join (encoded) (item # of (letter (i) of (val)) in [characters v] ::list))
change [i v] by (1)
end
if <((length of (cloud 1 ☁)) + (length of (encoded))) < (256)> then //checks if it would make it too large
set [cloud 1 ☁ v] to (join (cloud 1 ☁) (encoded))
else
if <((length of (cloud 2 ☁)) + (length of (encoded))) < (256)> then
set [cloud 2 ☁ v] to (join (cloud 2 ☁) (encoded)) // repeat for how may cloud variables you will use
end
end
Why are we adding the lengths?
join () (length of())
I am adding the lengths to the string so the code knows how much to read, because items will be next to eachother. “0” will be a common delimiter, because numbers don't start with 0 so we can use 0 as a way to tell the code that the length is longer than 9, therefore is a 2 digit number.

Why do we join encoded every time?
(join (encoded) ())
We join encoded every time because if we didn't, all previous encoded values would be deleted, if there were any. The join block, as shown in Section I, will add the previous item and the new one together, preserving the old encoded values.

Why does the item # block work?
(item # of () in [ v] ::list)
This works because say the character was “a”. If you go back to the part where we setup the lists, a would be item “10”, so the item # of “a” in the list would be 10, which is our encoded value. The “letter (i) of (value))” block gets each letter of the value you're encoding, and turns them into numbers with the “item # of” block. This also works with costumes, an alternate but longer way to encode, but has case sensitivity.

Section III: Decoding
Let's get complicated

Here comes the harder part, decoding. Decoding involves taking the numbers we've encoded, and then converting them into characters and numbers the lists understand. In short, we will be using the reverse of the “item #” of block, but instead will be using the “item () of” block. For costume encoding/decoding, you would use “costume name” instead of “costume number”.

To do so, we need a few custom blocks, and a few new variables, as shown below.
(val)
(letter)
define read letter
define read val amount (a)[s][/s]
These 2 blocks are the core of decoding, “reading” a singular letter and reading 2 letters. The code for these are simple, as shown below:
define read letter
set [letter v] to (letter (i) of (encoded))
change [i v] by (1)
this block “reads” a letter by finding the index letter of the encoded string, and setting the letter variable to that to be used for creating values.
define read value amount (a)
set [value v] to () //blank
repeat (a)
read letter ::custom
set [value v] to (join (value) (letter))
this block “reads” a value by finding the amount set of letters at the index of the encoded string, and putting them together for a single value.

Using these core building blocks of decoding, we can create a script to decode a single cloud value, with a new custom block, and 1 new variable.
(string)
define read value from cloud variable (c)
set [string v] to ()
if <(c) = (1)> then
set [encoded v] to (cloud 1 ☁)
else
if <(c) = (2)> then // continue as needed.
set [encoded v] to (cloud 2 ☁)
end
end
read letter :: custom
if <(letter) = (0)> then // for items longer than 9 characters
read value (2) ::custom
repeat (value)
read value (2) ::custom
set [string v] to (join (string) (item (value) of [characters v]))
end
else
repeat (letter) // for items less than 9 characters
read value (2) ::custom
set [string v] to (join (string) (item (value) of [characters v]))
end
end
if <(string) = ()> then
else
add (string) to [cloud list v]
And that's pretty much it for decoding!

How does it repeat the length?
In Section II, when we encoded the value we encoded the length with it so the code would know how much to read.

How does it turn the numbers into letters?
As stated in the beginning of this section, the opposite of “item # of” is “item () of” which converts item numbers into the item itself, which in this case is letters.

Section IV: Usability
How do i use this?

In your case, you're wanting to use cloud lists to store admins in your game, so when the flag is clicked you can do this:
define read cloud variable (c)
set [i v] to (1)
repeat until <(i) > (256)>
read value from cloud variable (c) :: custom

when green flag clicked
delete all of [cloud list v] ::list
read cloud variable (1)
read cloud variable (2) // continue as needed.
if <[cloud list v] contains (username) ::list> then
... // do admin things here
this will read all the the values from a cloud variables, and add the usernames into these list. In your case you also want to be able to add admins, then you can add admins like so:
define add admin user: (u) 
encode (u) to cloud ::custom
when gf clicked //or whenever you're adding admins
add admin user:(malicondi) // trollface example
Unfortunately, once all cloud variables are used, and all characters are used, (around 60 users, a lot of admins in my opinion) then you will have to manually add admins into the list for them to be checked.

I sincerely hope this helps, and if you need me to explain anything in more depth, then feel free to reply here, DONT quote the entire post, and I will explain whatever you need me to explain.

Last edited by Malicondi (March 20, 2024 01:17:35)


post #1000 post #100 i help in the forums post #1 post #500 0 second ninja
I recommend reading jvvg's essay about the scratch team before complaining, as it may change your opinion and provide insight on the topic.

coming soon :)


EPIC_SLAVER
Scratcher
13 posts

How do I make a cloud list?

thank you for all the effort put into that
thank (Malicondi)

LittleBigStinker
Scratcher
55 posts

How do I make a cloud list?

this will help me also thanks! but how come this does not work? https://scratch.mit.edu/projects/985903914

Last edited by LittleBigStinker (March 19, 2024 22:31:10)

-mage
New to Scratch
59 posts

How do I make a cloud list?

Malicondi wrote:

here comes another essay…

DISCLAIMER: DO NOT QUOTE ENTIRE POST

Making cloud lists are pretty complex, but i'll explain how to make one here. If you want case-sensitivity for your cloud list, that's more complicated since scratch sucks and “a” == “A” and i'll only explain it if you want me to. But for simplicity, I'll be using non-case-sensitive.

Section I: Cloud variables and Join
Ignore if you know about cloud variables, skip to section II.

To start out a cloud list, you first will need cloud variables, like this:
(☁ foo)
You can create a cloud variable if you're a Scratcher, and by clicking “create a new variable” and checking the “cloud variables” tickbox when creating the variable. It will give you an alert about its limitations that I will explain below

cloud variables are the base of cloud lists, because well they're cloud. Cloud variables can only store up to 256 characters, and we can only create 10 cloud variables, and of which ALL of the characters have to be a number, with a few exceptions.

The exceptions are “-” and “.”, where “-” can only be at the very beginning of the cloud variable, and “.” can only be inside of the cloud variable once at any point.

Because of these limitations, we must use encoding and decoding to send data and in this case “list items” to the project, over the server. If you don't know what encoding and decoding is, I recommend watching this video by griffpatch, as he explains it quite well.

The join block is another very essential block, that is required for encoding. The join block joins together, or “Concatenates” 2 values together. Here are some examples:
(join [hello] [world]) // returns "helloworld"
set [variable v] to [abc] // works with variables
(join (variable) [def]) // returns "abcdef", because the variable's value is abc.
(join [hi ] (join [there] [!])) // nested join blocks, this returns "hi there!"
You're going to see this block, and the
(letter () of ())
block a lot.

Section II: Encoding
Where the real code starts
Make sure every custom block is “run without screen refresh” or this will be slow.

As stated in Section I, because of these limitations we will have to encode and decode data in numbers to send over the cloud. There are a couple ways to do so, but i'll be using a way I prefer here, using lists with every character and number, that will be used.
First, create a custom blocks and a variable and a list, named anything, I prefer making all my variables “for this sprite only” unless I state not to.
(i) //short for index
(characters ::list)
define setup list
We can easily create a list with every character and number, like this:
define setup list
repeat (9)
add () to [characters v]
end
set [i v] to (0)
repeat (38)
change [i v] by (1)
add (letter (i) of [abcdefghijklmnopqrstuvwxyz1234567890-_]) to [characters v]
If you want more characters, just change the repeat by how many extra characters you're adding, and add them to the (letter() of() block, for example, if you wanted to add ^, then you would change repeat to 39 and the letter block to this:
(letter (i) of [abcdefghijklmnopqrstuvwxyz1234567890-_^])
Why did I add 9 blank values?
9 blank values are added to prevent anything from being encoded into 1 letter numbers, which will break decoding later on, and solve this issue, specifically for items with only numbers.

What is this list for?
This is what I'm about to cover, the list is used to convert characters into numbers using the
(item # of () in [ v] ::list) 
block. This block returns the item number of an item inside of a list, which we can use to convert every character into a number.

To do this, we will create a new block, and a new variable:
(encoded) // holding encoded numbers
define encode (val) to cloud
set [encoded v] to ()
if <(length of (val)) > (9)> then
set [encoded v] to (join (join (encoded) (0)) (length of (val)))
else
set [encoded v] to (join (encoded) (length of (val))
end
set [i v] to (1)// im back :)
repeat (length of (val))
set [encoded v] to (join (encoded) (item # of (letter (i) of (val)) in [characters v] ::list))
change [i v] by (1)
end
if <((length of (cloud 1 ☁)) + (length of (encoded))) < (256)> then //checks if it would make it too large
set [cloud 1 ☁ v] to (join (cloud 1 ☁) (encoded))
else
if <((length of (cloud 2 ☁)) + (length of (encoded))) < (256)> then
set [cloud 2 ☁ v] to (join (cloud 2 ☁) (encoded)) // repeat for how may cloud variables you will use
end
end
Why are we adding the lengths?
join () (length of())
I am adding the lengths to the string so the code knows how much to read, because items will be next to eachother. “0” will be a common delimiter, because numbers don't start with 0 so we can use 0 as a way to tell the code that the length is longer than 9, therefore is a 2 digit number.

Why do we join encoded every time?
(join (encoded) ())
We join encoded every time because if we didn't, all previous encoded values would be deleted, if there were any. The join block, as shown in Section I, will add the previous item and the new one together, preserving the old encoded values.

Why does the item # block work?
(item # of () in [ v] ::list)
This works because say the character was “a”. If you go back to the part where we setup the lists, a would be item “10”, so the item # of “a” in the list would be 10, which is our encoded value. The “letter (i) of (value))” block gets each letter of the value you're encoding, and turns them into numbers with the “item # of” block. This also works with costumes, an alternate but longer way to encode, but has case sensitivity.

Section III: Decoding
Let's get complicated

Here comes the harder part, decoding. Decoding involves taking the numbers we've encoded, and then converting them into characters and numbers the lists understand. In short, we will be using the reverse of the “item #” of block, but instead will be using the “item () of” block. For costume encoding/decoding, you would use “costume name” instead of “costume number”.

To do so, we need a few custom blocks, and a few new variables, as shown below.
(val)
(letter)
define read letter
define read val amount (a)[s][/s]
These 2 blocks are the core of decoding, “reading” a singular letter and reading 2 letters. The code for these are simple, as shown below:
define read letter
set [letter v] to (letter (i) of (encoded))
change [i v] by (1)
this block “reads” a letter by finding the index letter of the encoded string, and setting the letter variable to that to be used for creating values.
define read value amount (a)
set [value v] to () //blank
repeat (a)
read letter ::custom
set [value v] to (join (value) (letter))
this block “reads” a value by finding the amount set of letters at the index of the encoded string, and putting them together for a single value.

Using these core building blocks of decoding, we can create a script to decode a single cloud value, with a new custom block, and 2 new variables.
(string)
define read value from cloud variable (c)
set [string v] to ()
if <(c) = (1)> then
set [encoded v] to (cloud 1 ☁)
else
if <(c) = (2)> then // continue as needed.
set [encoded v] to (cloud 2 ☁)
end
end
read letter :: custom
if <(letter) = (0)> then // for items longer than 9 characters
read value (2) ::custom
repeat (value)
read value (2) ::custom
set [string v] to (join (string) (item (value) of [characters v]))
end
else
repeat (letter) // for items less than 9 characters
read value (2) ::custom
set [string v] to (join (string) (item (value) of [characters v]))
end
add (string) to [cloud list v]
And that's pretty much it for decoding!

How does it repeat the length?
In Section II, when we encoded the value we encoded the length with it so the code would know how much to read.

How does it turn the numbers into letters?
As stated in the beginning of this section, the opposite of “item # of” is “item () of” which converts item numbers into the item itself, which in this case is letters.

Section IV: Usability
How do i use this?

In your case, you're wanting to use cloud lists to store admins in your game, so when the flag is clicked you can do this:
define read cloud variable (c)
set [i v] to (1)
repeat until <(i) > (256)>
read value from cloud variable (c) :: custom

when green flag clicked
delete all of [cloud list v] ::list
read cloud variable (1)
read cloud variable (2) // continue as needed.
if <[cloud list v] contains (username) ::list> then
... // do admin things here
this will read all the the values from a cloud variables, and add the usernames into these list. In your case you also want to be able to add admins, then you can add admins like so:
define add admin user: (u) 
encode (u) to cloud ::custom
when gf clicked //or whenever you're adding admins
add admin user:(malicondi) // trollface example
Unfortunately, once all cloud variables are used, and all characters are used, (around 60 users, a lot of admins in my opinion) then you will have to manually add admins into the list for them to be checked.

I sincerely hope this helps, and if you need me to explain anything in more depth, then feel free to reply here, DONT quote the entire post, and I will explain whatever you need me to explain.
cool long text thanks
Sophie22Anne
Scratcher
18 posts

How do I make a cloud list?

Can you explain it simpler? Or just give the code?

Powered by DjangoBB