Saving Data
In a Scratch project, the act of saving data is to record a variable, list, or some other value so it can be read or used at a later time.
How it Works
When saving data, the variable, list, or value is converted into a code containing all of the currently saved data. This process is called encoding.
When the user would like to load the saved data, the saved code is converted back into the original values that were used to generate it. The project can then read and use these values like normal. This process is called decoding.
Common Uses
Common uses of data-saving systems in Scratch projects include:
- Storing player status in games
- Saving users' work in paint projects
This is not an exhaustive list; there are many more uses beyond those listed.
Making a Save Data System
Once the data is encoded, it is the user's responsibility to save the code for later. If the user wants to load their saved data, they must enter their code manually.
Encoding (Saving Data)
This is what the project will use to generate save codes.
define save (data) set [code v] to (join (join (code) [;]) (join (data) [;])
Now this custom block can be called whenever saving is needed. Here's an example of this block in action:
when flag clicked set [code v] to () when [s v] key pressed save (level):: custom save (coins):: custom
In this example, pressing S will save the "level" and "coins" variables into a single code.
Decoding (Loading Data)
Now the data is saved, what's left is to encode it and switch it back to the original so the project can use it. This can be done by reading each value in the (saved) code (by reading until a semi-column is read, then the system switches to reading the next value). Here is how:
Once the data is saved, the project must decode it so it can be read again. This is done by reading each portion of the code (separated by semicolons) and saving them into a list. The data can then be read by the project, just as it could before it was encoded.
This can be done in two ways. This is Method 1:
define load data (data) set [i v] to [1] //"i" is used so the system knows which letter it's reading. set [value v] to []//We'll add this to a list. repeat until <(i) > (length of (data))>//Start reading. repeat until <(letter (i) of (data)) = [;]>//Read letter by letter. set [value v] to (join (value) (letter (i) of (data))) change [i v] by (1)//So the system doesn't stick at one letter. end if <not <(value) = []>> then//Skips saving blank values, making it easier to tell which list item is which add (value) to [Loaded Data v]//So we can actually read the loaded value. end change [i v] by (1) set [value v] to []//Reset end
Alternatively, Method 2:
define load data (data) with the character (character) set [letter # v] to (1) delete all of [decoded v] repeat(length of (data)) if<(letter(letter #)of(data))=(character)> then add () to [decoded v] else replace item (length of [decoded v]:: list) of [decoded v] with (join(item(length of [decoded v]::list) of [decoded v])(letter(letter #) of (data)) end change [letter # v] by (1) end
Here's an example of Method 1 in action:
when flag clicked set [code v] to () when [l v] key pressed ask [Save code?] and wait load (answer) :: custom set [level v] to (item (1) of [Loaded Data v])// order of loading set [coins v] to (item (2) of [Loaded Data v])
In this example, pressing the L key will load the "level" and "coins" variables from the encoded data.
Encrypting Save Codes
The user can easily cheat by entering the desired values into the save code (e.g. they'll write "9999; 9999;" into the save code so "level" and "coins" will be 9999 rather than getting those values in the project) also known as "hacking" the save code, encrypting it may be necessary.
define save (data) set [code v] to (join(join (code) [; ]) ((data) * [43653])) when flag clicked set [code v] to () when [s v] key pressed save (level) :: custom blocks save (coins) :: custom blocks define load data (data) set [i v] to [1] set [value v] to [] repeat until <(i) > (length of (data))> repeat until <(letter (i) of (data)) = [;]> set [value v] to (join (value) (letter (i) of (data))) change [i v] by (1) end add ((value) / (43653)) to [Loaded Data v]//So it encodes it right. change [i v] by (1) set [value v] to [] end when [l v] key pressed ask [Save code?] and wait load (answer) :: custom blocks set [level v] to (item (1) of [Loaded Data v]) set [coins v] to (item (2) of [Loaded Data v])
That was an encrypted save data system which works by encoding and decoding the variables "level" and "coins". Шаблон:Note