Encode/Decode Save Data

I’ma make this quick and simple, because I have a mini game jam submission to work on. I’ve been trying to make a system where I can encode and decode the position, type, and variant of furniture in a game. And use the settings extension to save the data.

I made an encoder that would take a string of data, and convert it to a large ASCII code. The code would then be taken apart during the decoding process, and converted back to a normal string. It would then read the string and separate the data from it and load the settings along with the furniture itself.

Problems began when I finished the decoder, although it was originally supposed to decode a large number. It instead decoded a number with a ‘exponential notation’. After doing some more research, I found out the number was too large to simply be saved as the number itself.

I’m trying to get this system up quick so I can go back to working on content for my project. I tried looking into maybe making a encoder/decoder with Base32. But I don’t even know how I would start with something like that.

Any help is appreciated :+1:.

(P.S. sorry for the initial lack of screenshots and such. I’m currently on my phone at the moment, but I’ll try to attach some screenshots of code when I get the chance.)

@Unique you could try saving as a number array instead of a string!

My bad. I forgot to mention that the number value was added to the number array that would be saved with the settings extension.

The encoded data would look something like this:
“67726573820580686970658576840580540580530”

(NOT FULLY FUNCTIONAL)

Encoder:

function charToASCII (charInput: string) {
    output = ""
    for (let inx = 0; inx <= charInput.length; inx++) {
        foundCharAtInx = charInput.charAt(inx)
        let myVarAscii = foundCharAtInx.charCodeAt(0)
        output = "" + output + myVarAscii
    }
    console.log(output)
    return output
}

function placeFurniture (item: string) {
    if (item == "Default Comfort Chair") {
        recl = sprites.create(assets.image`myImage17`, SpriteKind.AddedFurniture)
        tiles.placeOnTile(recl, tiles.getTileLocation(selection_box.tilemapLocation().column, selection_box.tilemapLocation().row))
        // Encoding the item
        sprites.setDataString(recl, "type", "" + charToASCII("CHAIR") + charToASCII(":") + charToASCII("DEFAULT") + charToASCII(":") + charToASCII("" + recl.tilemapLocation().column) + charToASCII(":") + charToASCII("" + recl.tilemapLocation().row))
        console.log(sprites.readDataNumber(recl, "type"))
        last = 0
        for (let index = 0; index <= 5; index++) {
            encode_serperate = ""
            for (let index = 0; index <= Math.floor(("" + sprites.readDataNumber(recl, "type")).length / 5); index++) {
                encode_serperate = "" + encode_serperate + ("" + sprites.readDataNumber(recl, "type")).charAt(last + index)
            }
            last = last + (Math.floor(("" + sprites.readDataNumber(recl, "type")).length / 5) + 1)
            furniture.push(parseFloat(encode_serperate))
            console.log(encode_serperate)
        }
        blockSettings.writeNumberArray("savedFurniture", furniture)
    }
}

Decoder:

function LoadSavedFurniture () {
    furniture_data_decoded = ""
    for (let index = 0; index <= Math.floor(furniture.length) / 5; index++) {
        for (let index = 0; index <= 4; index++) {
            last = 0
            for (let index = 0; index <= Math.floor(("" + furniture[index]).length) / 2; index++) {
                decodeDouble = ""
                for (let index = 0; index <= 1; index++) {
                    decodeDouble = "" + decodeDouble + ("" + furniture[index]).charAt(index + last)
                }
                console.log(parseFloat(decodeDouble))
                console.log(String.fromCharCode(parseFloat(decodeDouble)))
                furniture_data_decoded = "" + furniture_data_decoded + String.fromCharCode(parseFloat(decodeDouble))
                last += 2
                console.log(furniture_data_decoded)
            }
        }
    }
}

Hmmm… what exactly are you trying to save? is there a reason you don’t just save the string itself instead of converting it into char codes?

I made a similar project recently where I stuck all of the save data into a single string and later decoded each variable into its own respective form. So it went from a save file looking like this:

name-str=My game/hardcore-bool=false/progress-int=3/stats-arrayInt=100&45&80&80&233&15/inventory-arrayStr=stone_axe*1&fish*6/day-int=6/time-int=2/respect-arrayInt=20#2414280

to clean data like this:

[
    "name": "My game", -> str
    "hardcore": false, -> bool
    "progress": 3, -> int
    "stats": [100, 45, 80, 80, 233, 15], -> arrayInt
    "inventory": ["stone_axe", "fish"], [1, 6], -> (arrayStr, arrayInt)
    "day": 6, -> int
    "time": 2, -> int
    "respect": [20] -> arrayInt
]
1 Like

Cool, but how would I read the string in order to give each value to it’s intended variable?

1 Like

Well since you’re asking, I actually made a file describing the encoding process so let’s dissect it together, shall we?
For first let’s load that save string and see what it’s made up of:

name-str=My game/hardcore-bool=false/progress-int=3/stats-arrayInt=100&45&80&80&233&15/inventory-arrayStr=stone_axe*1&fish*6/day-int=6/time-int=2/respect-arrayInt=20#2414280

For first we need to split each element on its own. I used the “/” character for this. (speaking of, make sure every character you use for splitting or other utilities can’t be typed on the makecode keyboard)

After splitting, you’ll get a string array that looks something like this
[ "name-str=My game", "hardcore-bool=false", ...] and so on.
now you need to understand that when decoding a string back into raw data, you need to know its type, which I encoded as ‘{key}-{type}={value}’

hardcore-bool=false
^⠀⠀⠀⠀⠀⠀^⠀⠀⠀⠀^
key⠀⠀⠀⠀type⠀⠀value

that means that now that we have such an array we have to loop through every value and save its key, value and type in some variables. then you can create a converter function that will parse the string based on the type and return the actual value

just have in mind you have to make a custom way to encode arrays, I did it as such:

stats-arrayInt=100&45&80&80&233&15

ofcourse, I set the type to arrayInt, and I separated each value with the “&” character. This was a showcase of how to do this in theory, and I have written code for this before, but in blocks and as part of another project. So if you do need any further assistance, simply ask and I can quickly scrap some showcase code for this

Thanks for the explanation! I hate to burden you, but do you mind providing some sample code? Some basic code is fine, no need for anything extravagant. I tried doing so myself earlier, and I still can’t put together any code for that works.

(also I would kinda like to put together a simple extension with some code.)

1 Like

I will provide some code but it’s late here so i could do it tomorrow. Besides that, when i finish it feel free to use it in any kind of extension or project you make.
P.S - if you check the save data I left above you can see a hashtag followed by some numbers at the very end, you can ignore that as it was an attempt at a checksum of some kind

1 Like