Codea 2.3: Lua 5.3

Hi Everyone

The changes for the Codea 2.3 are now listed here http://codea.io/talk/discussion/98/codea-roadmap-next-version-2-3-current-2-2

Codea 2.3 will cause some code breakage — nothing major, but it’s just something we have to deal with in the upgrade to Lua 5.3.

I’ve outlined the most common cases below:

#varargs

You’ve probably written varargs like this before, which is actually deprecated in Lua 5.1 (but it was allowed)

function foo(...)
    if arg.n > 0 then
        print(arg[1])
    end
end

You can rewrite this function right now the correct way in Lua 5.1, which will work with Lua 5.3 when Codea 2.3 comes out:

You’ve probably written varargs like this before, which is actually deprecated in Lua 5.1 (but it was allowed)

function foo(...)
    -- get the number of args
    local n = select('#', ...)

    -- make a table out of the args
    local arg = {...}

    if n > 0 then
        print(arg[1])
    end
end

#integers

Lua supports native integers now, which is awesome. But this means you can’t just give any old number to certain functions. Specifically math.random(int), math.random(int, int).

If you have a floating point number and want to convert it to an integer you can use math.floor to ensure it gets clipped. Lua will then convert it when it is passed to a function accepting integers. Not doing this will cause a runtime error.

(Note math.random() — no arguments, returns a floating point number as normal.)

Those are the big ones, and you can make your code compatible right now without impacting compatibility with the current version of Codea.

@Simeon If I have a game that uses math.random with integers and I don’t update yet until after releasing it, will the 2.3 runtime automatically be downloaded on export and bug out the game?

I’m slightly confused on how math.floor works. Like say if I have math.random(128, WIDTH-128), I have to use math.floor instead? If so, how would I do it? The above is actual code in a game I’m making and plan to submit to apple in the next few days.

@Crumble All math.floor does is to drop the decimal part of a number. example 23.12 will be 23, 56.999 will be 56, and 45.00 will be 45 .

@dave1707 I see.

So what if I had a division in math.random that gave a repeating decimal, 17/3 for example? The 5.666666666… result would cause an error and I would need to use math.floor? Is there a way to tell math.floor how many numbers past the decimal you want to keep, or does it always make it an integer?

Sorry for all the questions.

@Crumble math.floor always makes an integer. If you need a set number of digits past the decimal point for some reason, then string.format should be used.

@Simeon The following code gives red line editor errors. If you comment out the error line, the error will be on the next line. It will show an error for each line, but it will run and give the correct result. When I exit the program and go back to the editor, the red line error isn’t there anymore until I come back into the editor.

function setup()
    print("9&3 ",9&3)
    print("9|3 ",9|3)
    print("9~3 ",9~3)
    print("9>>2 ",9>>2)
    print("9<<2 ",9<<2)
end

@dave1707 try:

local var = 25.86789
print(math.floor(var*100)/100)

That should floor after two decimal places

@dave1707 that was fixed but Apple only allows two builds per 24 hours, so I still have to wait a few hours before I can release it for testing.

@Luatee I meant that there wasn’t any option in math.floor itself to give decimal places. But your way works just fine.

EDIT: The only problem with that option is the result isn’t rounded properly. The value 25.86789 would print as 25.86 . But a correct value to 2 decimal places should be 25.87 .

Maybe the simplest way to alter existing code is to define a new math.random function that makes adjustments like those above, then you don’t need to make any changes to existing code.

Whenever I want fractional random results, I always use math.random()*number

@Dave1707

local var = 25.86789
print(math.floor(var*100+0.5)/100)

This will mean that Ignatz may have to rewrite some of the tutorials on the Coolcodea website, otherwise some of the tutorials on there wont work properly with the new version of Codea.

:((

@Jmv38, nice trick, but as @dave1707 already said, this is what string.format is for. You shouldn’t be doing math to format things.

local var = 25.86789
print(string.format("%0.2f", var))

Sorry to make you cry Ignatz. Maybe you could write a program to automatically translate all of the code for you so it works on the new version of Lua/Codea, rather than editing it all manually?

They are pretty minor changes really. Most projects won’t need anything changed.

@juce - but if you’re not printing, but planning to use the number in calculations, string.format returns a string that Codea would have to convert back to a number, so I would use the method Luatee suggested in that case.

Perfect example that there’s always multiple ways to do something. You just need to think of what you want the outcome to be and write the code to do it.

@Luatee math.floor isn’t necessary in some cases, your example below:

local var = 25.86789
print(math.floor(var*100)/100)

Can be re-written

local var = 25.86789
print( var // 0.01 / 100 )

The // operator is the new integer division operator in Lua 5.3.

@Simeon I like that method a whole lot better, was this possible before 5.3 // operator?

Also my method is to floor/ceil to a decimal place not rounding.