Here’s the code as it stands if you just wanna give it a go:

```
--# Main
-- Ladderman
displayMode(FULLSCREEN)
supportedOrientations(PORTRAIT)
function setup()
PLAYING, LOST = 1, 2
MODE = PLAYING
stuffs()
initialise()
end
function draw()
background(255)
if MODE == PLAYING or MODE == LOST then
drawGame()
end
if MODE == LOST then
drawLost()
end
end
function touched(t)
if t.state == ENDED then
if MODE == PLAYING then
touchPlaying(t)
elseif MODE == LOST then
touchLost(t)
end
end
end
--# Playing
-- Just holds most of the functions for the playing state
-- Resets the game
function initialise()
ladders = {}
player = { x = rightX, y = sizes.ladder.y * 3.5, iid = 1, angle = 0 }
sign = { x = 0, y = sizes.ladder.y + sizes.sign.y / 2, alpha = 0 }
for r = 1, math.ceil(HEIGHT / sizes.ladder.y) + 1 do
addRow(true)
end
groundO = sizes.ladder.y
score = 0
highscore = readLocalData("highscore") or 0
time = .5
if timeT ~= nil then tween.stop(timeT) end
canMove = true
end
-- Draws everything for the playing state
function drawGame()
-- Draw the 'bulding' background
for bi = #ladders, 1, -2 do
sprite(imgs.brick, WIDTH / 2, ladders[bi].y, WIDTH, sizes.ladder.y)
end
-- Draw the ladders
for li = #ladders, 1, -1 do
local ladder = ladders[li]
if not ladder.hole then
sprite(imgs.ladder, ladder.x, ladder.y, sizes.ladder.x, sizes.ladder.y)
end
end
-- Draw the player
pushMatrix() translate(player.x, player.y) rotate(player.angle)
sprite(imgs.player[player.iid], 0, 0, sizes.player.x, sizes.player.y)
popMatrix()
-- Draw the ground if it is still onscreen
if groundO < sizes.ladder.y then
sprite(imgs.ground, WIDTH / 2, sizes.ladder.y / 2 - groundO, WIDTH, sizes.ladder.y)
end
-- Draw the timer bar
local o = WIDTH / 200
local a = (rightX - sizes.ladder.x / 2) - (leftX + sizes.ladder.x / 2)
sprite(imgs.bar[1], WIDTH / 2, HEIGHT - HEIGHT / 40, a, HEIGHT / 20)
sprite(imgs.bar[2], WIDTH / 2, HEIGHT - HEIGHT / 40, (a - o*1.8) * time, HEIGHT / 20 - o*1.8)
-- Draws the score and then the highscore right below it
sprite(imgs.panel, WIDTH / 2, HEIGHT / 2, a / 1.5)
font(GAMEFONT)
fill(0) if score >= highscore then fill(255,0,0) end fontSize(WIDTH / 10)
text(score, WIDTH / 2, HEIGHT / 2)
fill(255,0,0) fontSize(WIDTH / 20)
text(math.max(highscore, score), WIDTH / 2, HEIGHT / 2 - fontSize() * 1.5)
fill(0)
text("SCORE", WIDTH / 2, HEIGHT / 2 + fontSize() * 1.5)
stroke(0, 155, 255, 153) strokeWidth(oneS * 2)
line(WIDTH / 2 - a / 3.27, HEIGHT / 2 - fontSize(), WIDTH / 2 + a / 3.27, HEIGHT / 2 - fontSize())
line(WIDTH / 2 - a / 3.27, HEIGHT / 2 + fontSize(), WIDTH / 2 + a / 3.27, HEIGHT / 2 + fontSize())
-- Lost / died sign
tint(255, sign.alpha)
sprite(imgs.sign, sign.x, sign.y, sizes.sign.x, sizes.sign.y)
noTint()
end
-- Losing sequence
function fall()
canMove = false
if timeT ~= nil then tween.stop(timeT) end
tween(.75, _G, { groundO = 0 })
falling = tween(.75, player, { y = 0, angle = 230 }, tween.easing.linear, function()
sign.x = player.x + sizes.ladder.x / 2 + sizes.sign.x / 1.75
if player.x == leftX then sign.x = player.x - sizes.ladder.x / 2 - sizes.sign.x / 1.75 end
falling = tween(.5, sign, { alpha = 255 }, tween.easing.linear, function()
animateEndMenu()
MODE = LOST
end)
end)
end
-- Adds another row to the top of the ladder
function addRow(rnok)
local y
if #ladders == 0 then y = sizes.ladder.y / 2
else y = ladders[#ladders].y + sizes.ladder.y end
local rand = math.random(1, 5)
local rhole, lhole = false, false
if not rnok then
if rand == 2 and lastRand ~= 3 then rhole = true
elseif rand == 3 and lastRand ~= 2 then lhole = true end
end
lastRand = rand
table.insert(ladders, { x = rightX, y = y, hole = rhole })
table.insert(ladders, { x = leftX, y = y, hole = lhole })
end
-- Checks if the player is in a hole
function checkLoss()
for li = #ladders, 1, -1 do
local ladder = ladders[li]
if ladder.hole and ladder.x == player.x and math.abs(ladder.y - player.y) < sizes.ladder.y / 2 then
if score > highscore then
saveLocalData("highscore", score)
end
fall()
return true
end
end
return false
end
-- Moves ladders and player, and calls to check if player is in a hole
function moveObjects(right)
canMove = false
player.iid = 2
if right then
player.x = rightX
else
player.x = leftX
end
checkLoss()
for li = #ladders, 1, -1 do
local ladder = ladders[li]
tween(0.04, ladder, { y = ladder.y - sizes.ladder.y })
if ladder.y < 0 then
table.remove(ladders, li)
end
end
tween.delay(0.04, function()
addRow()
if not checkLoss() then
player.iid = 1
score = score + 1
canMove = true
end
end)
end
-- Adds a bit of time to the timer
function addToTimer()
if timeT ~= nil then
tween.stop(timeT)
timeT = nil
end
time = math.min(time + .04, 1)
timeT = tween(time * 8, _G, { time = 0 }, tween.easing.linear, fall)
end
-- All the touch code for the playing state
function touchPlaying(t)
if canMove then
moveObjects(t.x > WIDTH / 2)
addToTimer()
end
end
--# Lost
-- Just holds most of the functions for the lost state
function animateEndMenu()
tween(.5, replay, { y = HEIGHT / 2 })
end
function animateHideEndMenu()
tween(.5, replay, { y = HEIGHT + sizes.replay.y / 2 }, tween.easing.linear, function()
initialise()
MODE = PLAYING
end)
end
function drawLost()
sprite(imgs.panel, replay.x, replay.y, sizes.replay.x, sizes.replay.y)
stroke(0, 155, 255, 153) strokeWidth(oneS * 2)
local lof, sof, tof = sizes.replay.x / 2.17, sizes.replay.y / 4, sizes.replay.y / 9
line(replay.x - lof, replay.y - sof, replay.x + lof, replay.y - sof)
line(replay.x - lof, replay.y + sof, replay.x + lof, replay.y + sof)
fill(0) fontSize(WIDTH / 8)
text("GAME OVER", replay.x, replay.y + sof + tof)
text("PLAY AGAIN?", replay.x, replay.y - sof - tof)
end
function touchLost(t)
if t.x >= replay.x - sizes.replay.x / 2 and t.x <= replay.x + sizes.replay.x / 2
and t.y >= replay.y - sizes.replay.y / 2 and t.y <= replay.y - sizes.replay.y / 4 then
animateHideEndMenu()
end
end
--# Variables
function stuffs()
GAMEFONT = "Futura-CondensedMedium"
oneS = WIDTH / 768
local bimg, gimg = makeImgs()
imgs = {
ladder = readImage("Dropbox:ladder_mid"),
player = { readImage("Dropbox:alienGreen_climb1"), readImage("Dropbox:alienGreen_climb2") },
ground = gimg,
sign = readImage("Dropbox:signRip"),
brick = bimg,
bar = { readImage("Dropbox:barHorizontal_shadow_dark_full"), readImage("Dropbox:barHorizontal_red_full") },
panel = readImage("Dropbox:glassPanel_corners")
}
sizes = {
ladder = vec2(WIDTH / 9, HEIGHT / 9),
player = vec2(WIDTH / 10, HEIGHT / 9.5),
sign = vec2(WIDTH / 8, HEIGHT / 9),
replay = vec2(WIDTH / 1.5, WIDTH / 1.5)
}
replay = { x = WIDTH / 2, y = HEIGHT + sizes.replay.y / 2 }
leftX = WIDTH / 3.5
rightX = WIDTH * 2.5/3.5
end
function makeImgs()
local brickImg = image(WIDTH, HEIGHT / 9) setContext(brickImg)
for i = 1, 9 do
sprite("Dropbox:stoneCenter", -WIDTH / 18 + (WIDTH / 9) * i, HEIGHT / 18, WIDTH / 9, HEIGHT / 9)
end
setContext()
local groundImg = image(WIDTH, HEIGHT / 9) setContext(groundImg)
for i = 1, 9 do
sprite("Dropbox:grassMid", -WIDTH / 18 + (WIDTH / 9) * i, HEIGHT / 18, WIDTH / 9, HEIGHT / 9)
end
setContext()
return brickImg, groundImg
end
```

You will have to use placeholder sprited though… (they are all defined in the variables tab, under fairly clear names so you could pick something that fits)

I plan to add a formal menu screen at the beginning and redo the replay screen as I’m not super pleased with it.