Codea 1.5 (Beta 12)

Hello @Simeon. I am working through some of the open issues on the Issue Tracker in connection with beta 1.5(12).

####Issue No. 217
I find that os.time() does change from one value to another as time passes, but about once every two minutes.


--
-- os.time
--

function setup()
    timeCheck()
end

local trialCount = 0
function timeCheck()
    local timeValue = os.time()
    local dateString = os.date("%c", timeValue)
    trialCount = trialCount + 1
    print(trialCount..": "..dateString)
end

function draw() background(0) end

function touched(touch)
    if touch.state == BEGAN then timeCheck() end
end

.@mpilgrem this is due to Codea using 32 bit floats for the Lua “number” type instead of the default 64 bit double-precision float (“double”). This is because there are performance benefits to using single-precision floats on the newer iPad ARM CPUs.

So what is happening is the value from os.time() is getting truncated, and small changes are lost.

.@Simeon, in the past you have explained (here) that Codea’s use of a version of Lua that uses singles rather than doubles for Lua’s number type is to accommodate the performance of first generation iPads. Do you see a time where you might have an ‘enhanced’ version of Codea that is not intended to work well on first generation iPads?

This is almost certainly not on any critical path for Codea version 1.5, but I see from the Lua reference that the meaning of the value returned by os.time([table]) (and understood by os.date()) is allowed to vary from system to system.

Perhaps the Codea ‘system’ could change (behind the scenes) the start of the ‘epoch’ (update: from the 1 January 1970 GMT used by iOS) so that the number of seconds since that start fell within the precision of a 32 bit float?

(Further update): A little knowledge is a dangerous thing, but I think it would involve something like this patch in loslib.c:

(1) deducting some offset value (say, CODEA_EPOCH_OFFSET) from these lines:


static int os_time (lua_State *L) {
  time_t t;
  if (lua_isnoneornil(L, 1))  /* called without args? */
    t = time(NULL) - CODEA_EPOCH_OFFSET;  /* get current time */
  else {
    ...
    t = mktime(&ts) - CODEA_EPOCH_OFFSET
  }
  ...

(2) adding back the same offset value in this line:


static int os_date (lua_State *L) {
  const char *s = luaL_optstring(L, 1, "%c");
  time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL))
    + CODEA_EPOCH_OFFSET;
  ...

####Issue No. 216

What the code below allows you to explore is (1) the odd behaviour of line() when smooth is set and strokeWidth is less than 2.5; and (2) that the line width does not scale if noSmooth is set.


--
-- Scale-Stroke-Smooth Explorer
--

function setup()
    red = color(255, 0, 0)
    green = color(0, 255, 0)
    parameter.number("scaleValue", 1, 20, 10)
    parameter.number("strokeWidthValue", 1, 10, 5)
    parameter.boolean("isSmooth", true)
    rectMode(CENTER)
    stroke(255)
end

function drawPattern()
    fill(green)
    strokeWidth(strokeWidthValue)
    if isSmooth then
        smooth()
    else
        noSmooth()
    end
    line(-20, 10, 20, 10)
    rect(0, -20, 40, 20)
end

function draw()
    background(0)
    translate(WIDTH / 2, HEIGHT * 0.9)
    noStroke()
    fill(red) ellipse(0, 0, 5) -- Mark origin
    drawPattern()
    translate(0, - HEIGHT * 0.45)
    noStroke()
    fill(red) ellipse(0, 0, 5) -- Mark origin
    scale(scaleValue) -- Scale up
    drawPattern()
end

Is there a companion statement to saveProjectTab() that creates a new project?

Editor bug. Paste this into an empty tab, and try to remove the O.

        local b = UI.TextButton {x=i*135, y=180, w=130, h=30, title="O" .. i,output = i}
   

Works fine if I add a line break though. Current version is quite stable and nice. :slight_smile:

.@mpilgrem that’s a great demo — I’ve used it to improve the line shader with round end caps in the next build (though it’s probably a bit slower now).

The reason noSmooth() lines don’t scale in width is because they use the GL_LINE primitive. This primitive is not affected the same way by vertex transforms because it only has two vertices. We could change to drawing a rect (internally) for noSmooth() lines, this would allow all four vertices to scale but would be slower.

CODEA_EPOCH_OFFSET is an interesting idea. It would make os.time() a lot more useful, and we could disable it in case we do move to double precision numbers in the future.

.@tnlogy I can’t recreate this — is it causing the text input to become misaligned on your device?

.@Mark not for version 1.5, but I am keeping that one in mind.

Hello @Simeon. The following is an Editor bug, but the solution may lie with changing the color() function.

The argument pop-up ‘tips’ in the Editor suggest that when color() has a single argument, it is a ‘Gray Value’, and when color() has two arguments, the first is ‘Gray’ and the second ‘Alpha’.

However, color() only allows for color(red, green, blue, alpha) with red, green and blue assumed to be 0 if they are not supplied and alpha assumed to be 255 if it is not supplied.

Perhaps it would be better if color() behaved more like fill() does, in terms of its arguments? - although that would be a change in the Codea API.

####Issues No. 195 and 196

myBody.linearDamping and myBody.angularDamping still return boolean values, in error, and are not documented in the in-app reference for ‘physics.body’.


--
-- Dampner
--

function setup()
    physics.gravity(0, 0)
    myBody = physics.body(CIRCLE, 30)
    
    -- number, used to reduce the velocity of the body. The
    -- default, 0, is no damping. Damping is usually less
    -- than 1, but can be greater.
    myBody.linearDamping = 0.5
    
    -- number, used to reduce the angular velocity of the body.
    -- The default, 0, is no damping. Damping is usually less
    -- than 1, but can be greater.
    myBody.angularDamping = 0.5
    -- Codea bug:
    print(myBody.linearDamping) -- Output: false
    print(myBody.angularDamping) -- Output: false
    
    myBody.linearVelocity = vec2(1, 2)
    myBody.angularVelocity = 1
    myBody.sleepingAllowed = false
    fill(255)
    fontSize(32)
    title = "time: (v_x, v_y), w"
end

function draw()
    background(0)
    s = string.format("%.1f: (%.2f, %.2f), %.2f",
        ElapsedTime, myBody.linearVelocity.x,
        myBody.linearVelocity.y, myBody.angularVelocity)
    text(title, WIDTH / 2, HEIGHT / 2 + 50)
    text(s, WIDTH / 2, HEIGHT / 2)
end

Thanks @mpilgrem. I’ve fixed the physics.body issues (and docs). I’ve also modified color() to behave similarly to fill() and stroke().

About the edit bug, it only happens in portrait mode. When I hit backspace it removed the letter 10 steps to the right instead of O.

.@tnlogy thanks, I was able to reproduce the issue. I can’t actually fix this bug without rewriting the editor (which is currently in the works — just probably not for 1.5). Is it a common occurrence for you?

I can live with it. Works fine if I line wrap a bit earlier, quite ok to work around.

####Issue No. 161
I believe that the following still apply to the ‘Physics’ chapter of the in-app reference:

(1) categories and mask are not documented in the in-app reference for ‘physics.body’:

categories: table, an array of the categories (0 to 15) to which the body belongs for collision filtering. The default is {0}.

mask: table, an array of the categories of bodies with which the body will collide. The default is all categories, {0, 1, …, 14, 15}.

(2) the in-app reference for ‘physics.body’ does not document the default value for friction (0.2).

(3) the in-app reference documents the last argument of a PRISMATIC joint as an anchor. Test2 implies that it is a directional vector.

Small bug with setContext. Don’t know if anyone else has seen it. In this example the image drawn into setContext it cut at 493x120 instead of 560x120 which is the image size. But it is rendered correct when created from the touch event.


function setup()
    displayMode(FULLSCREEN)
    createColorImage()
end

function draw()
    background(40, 40, 50)
    spriteMode(CENTER)
    sprite(colorImage, WIDTH/2, HEIGHT/2)
end

function touched()
    createColorImage()
end

function createColorImage()
    colorImage = image(560,120)
    setContext(colorImage)
    background()
    spriteMode(CORNER)
    sprite("Documents:ColorPicker", 0,0, 560)
    setContext()
end

.@mpilgrem thank you for the detailed corrections. I’ve used your descriptions for categories and mask for now, and sent them to @John so he can review them (he’s the physics guy).

.@tnlogy I am trying this with other images and can’t seem to reproduce. Perhaps you should try changing your createColorImage function to the following:


function createColorImage()
    colorImage = image(560,120)
    setContext(colorImage)
    background(0,0,0,0) -- Use a transparent background
    spriteMode(CORNER)
    sprite("Documents:ColorPicker", 0,0, 560)
    setContext()
end

Maybe the black background just makes it look as if your image is getting cut off?

Strange. I use an iPad2. A workaround for me is to do like this in setup instead. I can mail you the image if you like.

    tween(.2,{},{}, "linear", createColorImage)

Thanks @tnlogy — I’ll give it a try on iPad 2 and see how your code goes. I’ve added your example to my bug list, so I’ll check it out before the next build.

Edit: also closing this thread. Beta 13 discussion is now here: http://twolivesleft.com/Codea/Talk/discussion/2109/codea-1.5-beta-13