How to use playdate.datastore.read([filename])?

I know, I suck at coding, I just really need help (for the 7-billionth time). I can't figure out how to use playdate.datastore.read([filename]). I have this:

import "CoreLibs/graphics"

import "CoreLibs/object"

import "CoreLibs/sprites"

import "CoreLibs/nineslice"

import "CoreLibs/timer"

import "CoreLibs/graphics"

import "CoreLibs/ui"

import "CoreLibs/animation"

import "CoreLibs/animator"

import "CoreLibs/crank"

import "config"

import "core/definitions"

import "core/cotton/all"

import "scripts/index"

import "core/lieb/all"

import "core/CoreGame"

save = {

    money = 100,

    billValue = 20,

    managers = 4,

    printers = 5,

    lastTime = playdate.getTime()

}

save = playdate.datastore.read(data)

playdate.ui.crankIndicator:start()

local gfx <const> = playdate.graphics

local printerSprite = nil

local function initialize()

    printerImage = gfx.image.new("images/Printer")

    printerSprite = gfx.sprite.new(playerImage)

    printerSprite:moveTo(200, 120)

    printerSprite:add()

end

initialize()

LDtk.load("levels/world.ldtk", shouldUseFastLoader())

if playdate.isSimulator then

    LDtk.export_to_lua_files()

end

local printerPicture = playdate.graphics.image.new("images/printer")

local cashPicture = playdate.graphics.image.new("images/cash")

local animatorY = playdate.graphics.animator.new(2000, 120, 240)

local myInputHandlers = {

    cranked = function(acceleratedChange)

        -- use the printer

        if acceleratedChange > 50 then

            if printers ~= 0 then

                money = money + (billValue * printers)

            end

        end

    end,

}

local menu = playdate.getSystemMenu()

playdate.gameWillPause = function()

    menu:removeAllMenuItems()

    if money >= 100 then

        local addPrinter = menu:addMenuItem("+Printer", function()

            money = money - 100

            printers = printers + 1

        end)

    end

    if money >= 150 then

        if managers <= printers then

            local addManager = menu:addMenuItem("+Manager", function()

                money = money - 150

                managers = managers + 1

            end)

        end

    end

    if billValue == 20 then

        if money >= 1000 then

            local billValueIncrease20 = menu:addMenuItem("+Bill Value", function()

                money = money - 1000

                billValue = 50

            end)

        end

    end

    if billValue == 50 then

        if money >= 2000 then

            local billValueIncrease50 = menu:addMenuItem("+Bill Value", function()

                money = money - 2000

                billValue = 100

            end)

        end

    end

end

scene.set(game, LDtk.playerStartLocation)

function playdate.update()

    input.update()

    gfx.sprite.update()

    scene.update()

    if config.showFPS then

        playdate.drawFPS()

    end

    if playdate.isCrankDocked() == true then

        if printers >= 1 then

            playdate.ui.crankIndicator:update()

        end

    end

    playdate.timer.updateTimers()

    playdate.inputHandlers.push(myInputHandlers)

    playdate.graphics.drawText("*Money:* " .. money, 40, 200)

    playdate.graphics.drawText("*Printers:* " .. printers, 20, 25)

    printerPicture:draw(100, 60)

    if playdate.getCrankChange == 50 then

        cashPicture:draw(170, animatorY:currentValue())

    end

    cashPicture:draw(170, animatorY:currentValue())

end

function playdate.gameWillTerminate()

    playdate.datastore.write(save, data)

end

function managerManaging()

    if managers > 0 then

        money = money + (billValue * managers)

    end

end

playdate.timer.keyRepeatTimerWithDelay(5000, 5000, managerManaging)

I'm trying to save how much money, managers, printers, and the bill value each time you close the game so that it's the same when you open it back up, but I checked the JSON file that it created, and it was exactly the same as what I declared the variables at at the top. I also need the time so that I can subtract the time when the game was last closed with the time when it's opened to determine how much money you've made. Can you help with this stuff? I want to finish this game today, because I don't have a lot of free time tomorrow, and the deadline is 7:00 tomorrow. Also, I need to play an animation when you use the crank, but if you use the crank really fast, it needs to duplicate and not just reset. Can you guys please help with this?

1 Like

I see a couple different issues happening. First, the filename for datastore should be a string, so it should look like playdate.datastore.read("data") and playdate.datastore.write(save, "data").

Second, you aren't actually updating your save table before you save it to disk. To fix this, you should add save. before you use your variables. So save.money, save.billValue, save.managers, and save.printers. You'll have to go through your code and make sure you are modifying the save table instead of the global variables.

For saving the time, you'll just need to update it right before you save to disk:

function playdate.gameWillTerminate()
    save.lastTime = playdate.getTime()

    playdate.datastore.write(save, "data")
end

OK thanks. Do you have an idea of how I could fix the animations?

Also, when I build/run it in the simulator, I get this error:

Update error: main.lua:136: attempt to compare number with nil
stack traceback:
main.lua:136: in function 'managerManaging'
CoreLibs/timer.lua:153: in local 'callCallback'
CoreLibs/timer.lua:167: in field 'keyRepeatTimerWithDelay'
main.lua:144: in main chunk

I don't know why

if you change the code where you read in the data to this:

save = playdate.datastore.read("data") or {

    money = 100,

    billValue = 20,

    managers = 4,

    printers = 5,

    lastTime = playdate.getTime()
}

Does that fix the error?

No, it doesn't. Sorry I took a while to respond, I started decorating my christmas tree and just checked back. I'm still getting the error

Update error: main.lua:147: attempt to compare number with nil
stack traceback:
main.lua:147: in function 'managerManaging'
CoreLibs/timer.lua:153: in local 'callCallback'
CoreLibs/timer.lua:167: in field 'keyRepeatTimerWithDelay'
main.lua:155: in main chunk

Did you make sure to add save. before all your save variables? Does your new managerManaging function look like this:

function managerManaging()
    if save.managers > 0 then
        save.money = save.money + (save.billValue * save.managers)
    end
end

Oh, I just missed a couple of save. prefixes. Thanks :smiley:. Also, I am trying to have an animation that you probably saw in the code play when you use the crank. However, I don't know how to make it duplicate instead of resetting if you crank it really fast. Do you have an answer?

Sorry, I don’t really understand what animation you are trying to make

Basically it’s just a picture of money coming out of the printer—the game is an idle game where you basically have to print money, so I just have a picture of cash that scrolls down from where the printer picture is. Sorry I didn’t make that clear before

and if I can finish this, then I have officially made the FIRST PLAYDATE IDLE GAME (that I can find) and probably not get it into season 2 lol but at least I get experience

Aa ok, so you want there to be multiple money images falling when cranking faster?
What you could do is create new animator objects when cranking within an array/table and then loop trough this array drawing the money images for each animators current value. But if you do it like this make sure to remove the animator from the array when it is done.

ummmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm ok if I can figure it out :joy:

OK I figured out what to do, but I can't get it to actually play when I crank. I added the line to the input handlers, I don't know if that's what I should be doing.

Here is an example of what you could do:

local animators = {}

-- Call this where you want to add a new animator
function addAnimator()
    animators[#animators+1] = playdate.graphics.animator.new(2000, 120, 240)
end

function playdate.update()
    ...


    for index, value in ipairs(animators) do
        cashPicture:draw(170, value:currentValue())
    end

    for i=#animators,1,-1 do
        if animators[i]:ended() then
            table.remove(animators, i)
        end
    end
end

I’m not sure if it works as I haven’t tested it, but it’s a start. Good luck

Thanks for helping with all of this! I would never have been able to even start making this game if it weren't for this forum :smiley:

No problem, it one of the reasons this forum exits :blush:

You know, the playdate is literally the perfect console for me. It is vintage and retro, but modern at the same time, and pretty much made for devs to tinker with, which is my specialty (hence the pile of broken macbooks with windows 8.1 in my basement lol).

Yeah, it's an amazing console. I can't wait until i get mine :joy:

same, I'm hopefully gonna preorder it on christmas so I can get it around my birthday