Save function different now - possible OS bug

Hi, I don’t know if it’s something to do with iOS 9.3 but save and read code in codea is throwing up an error:

Attempt to concatenate a nil value

This is happening with a nice piece of code someone on the forum kindly wrote that assigns graphic numbers to the score drawn on the screen. The score works but when I save the score if it beats the highscore that loaded highscore throws up the above error.

Now the code I’m using was definitely working back when I made mightymower. And in fact the mower app that’s live on the Apple Store works. But this locally in codea runtime is causing this new error.

I’m working on my new game starsceptre and reusing the code to pull in a variable I’ve saved.

The only thing I can think of is when I print() that variable it’s now showing with a decimal point (say 72310.0) but I only use whole numbers. I imagine it’s having a hissy fit over the decimal. Can I tell it to ignore it and save only a number with whole numbers?

Thanks
Rich

@Majormorgan The error message is telling you everything you need to know. You’re trying to concatenate a nil value. Try using a print statement to print the valuables you’re using and see which one contains the nil value.

EDIT: The decimal point isn’t the problem.

Thanks @dave1707 I’ll re-check but I thought I had already printed these variables and none showed a nil.

Also the original code worked in my other game and I haven’t changed that code since it was last finished and output to the store two years ago. Yet now it is showing the same error. I’ll check again and come back to you. Thanks for your help. Rich

Edit:
Would the decimal point be the issue if it’s drawing the numbers it’s expecting to but hasn’t got anything set up to handle the decimal point (I.e I’ve only got code and graphic numbers for 0-9 and nothing for a ‘.’ ?

@Majormorgan If you run the below code, you’ll see that variables a and b can be concatenated together even though ones a number, the other is a string, and they both have decimal points in them. The error comes trying to concatenate variable c, which is a nil. The error message even tells you that the variable c is nil.

function setup()
    a=1.234
    b="9.876"
    c=nil
    z=a..b
    print(z)
    z=a..b..c
end
Main:9: attempt to concatenate a nil value (global 'c')
stack traceback:
	Main:9: in function 'setup'

Cool thanks @dave1707 I’ll check it all out again. It is weird as I’m not trying to concatenate anything. I’ll come back to you. Many thanks again!!!

Hey @dave1707 - you’re right in that I found what was ‘nil’

I checked the variable and it is correct. No ‘nil’ or undefined in the score or highscore.

But where the problem is, is in the code that takes the highscore and breaks it down into the individual numbers. it is the ‘.’ as the highscore code doesn’t have something to deal with the ‘.’ Character. By writing in a piece to detect the decimal place I’ve substituted it with a zero character and it shows no problem. The full stop was the ‘nil’ part as scores never used to save with a decimal.

So what I need now is for the number not to write the decimal place and the number below a full number or not to read it as it is a whole score. Or I need to leave off the last two characters.

So a score like 32000 needs to stay 32000 and not 32000.0 as is currently being saved.

So currently this adding two zeroes to the score - so 32000.0 is becoming 3200000 and I don’t want that.

Is the decimal a new thing in a recent version of codea? I have to admit the score code was last run two years ago and so the numbers then were either whole or they were ignored previously.

Below is my code and I’ve annotated the bit I corrected


Scoretime = class()

function Scoretime:init(typ)
    --note how you have to set each of the ten key-value pairs in this case
    -- no need to put the Documents:num prefix on all of them
    -- we can do it later, below
    --check I have all the quotes correctly placed
    self.typ=typ
    self.va=score
    self.pos=scalerX*45
    self.Num = {["0"]="Zero",["1"]="One",["2"]="Two",["3"]="Three",
                      ["4"]="Four",["5"]="Five",["6"]="Six",["7"]="Seven",
                      ["8"]="Eight",["9"]="Nine",

                      ["."]="Zero" -- this is the part I added to correct the 'nil'

             }

    
end

function Scoretime:draw()
    if self.typ==1 then self.va=score
        self.pos=scalerX*-5
    else self.va=highscore
        self.pos=scalerX*50
    end
    for i=1,string.len(self.va)do
        
        local d=string.sub(self.va,i,i) --d contains a digit like "4"
        --now we add the Documents:num prefix to the number
        if sz==0 then
            scoreplace=scalerX*22
            --[[if score<10 then scoreplace=scalerX*25
            elseif score>9 and score<100 then scoreplace=scalerX*35
            elseif score>99 and score<1000 then scoreplace=scalerX*35
            elseif score>999 and score<10000 then scoreplace=scalerX*35
            elseif score>9999 and score<100000 then scoreplace=scalerX*35
            end]]--
            sprite("Project:num"..self.Num[d],scoreplace+i*scalerX*3.75+self.pos,scalerY*95+yyy,scalerX*5,scalerY*5)
        else
            
            if self.va<10 then scoreplace=scalerX*13+self.pos
            elseif self.va>9 and self.va<100 then scoreplace=scalerX*11+self.pos
            elseif self.va>99 and self.va<1000 then scoreplace=scalerX*9+self.pos
            elseif self.va>999 and self.va<10000 then scoreplace=scalerX*7+self.pos
            elseif self.va>9999 and self.va<100000 then scoreplace=scalerX*5+self.pos
            end
            sprite("Project:num"..self.Num[d],scoreplace+i*scalerX*2.5+self.pos,soy+yyy,scalerX*10,scalerY*10)
            
        end
    end
end


Thanks

Also I remembered who helped write the original awesome code and it was the mighty @Ignatz - the code works a dream, but t I think saving numbers have changed recently in Codea hence this new issue

@Majormorgan If you want a number without the decimal, try math.floor. See the code below.

function setup()
    a=1.234
    print(math.floor(a))
end

Awesome check it out now @dave1707 ! Thank you for all your awesome help!!!

Ok so I’ve just tried this:

math.floor(highscore)

I don’t think I can floor a variable, unless I’m missing something?

It would be variable=math.floor(some variable)

Ah I see! Awesome

That’s the one! Thank you @dave1707 !!! Epic

If that’s @Ignatz code, then he will make a permanent fix for it. He should be waking up in an hour or so.

Cool! I’ve added the floor code to the game’s main setup so when it loads the highscore it pulls in and removes the decimals. So cool. Thank you.

@Majormorgan Maybe this will make it clear as to what’s happening. If a variable is an integer, it will remain an integer. If a variable is a floating point, it remains a floating point. If a variable is a mix, integer and floating point, it’s a floating point.

P.S. Integer math was added a few releases ago, so that probably altered the way thing now work.

function setup()
    a=1
    b=1
    c=1.0
    print("a="..a)
    print("b="..b)
    print("c="..c)
    d=a+b
    print("a+b="..d)
    e=a+b+c
    print("a+b+c="..e)
end

@dave1707 why aren’t you rude anymore? Like earlier.

@TokOut - Majormorgan had a problem and after getting initial advice, he figured out how to fix it, and posted a full explanation which is helpful to others. He didn’t expect Dave to do everything for him. That’s the difference.