Code Examples
Learn by example — from Hello World to full games.
1. Hello World & Moving Text
Beginner
The simplest game: move a text label around the screen with the arrow keys.
Demonstrates cls, print, btn.
function _init() x, y = 64, 120 end function _update() if btn(0) then x -= 2 end if btn(1) then x += 2 end if btn(2) then y -= 2 end if btn(3) then y += 2 end -- clamp to screen x = mid(0, x, 190) y = mid(0, y, 248) end function _draw() cls(1) print("HELLO PLUTO-8!", x, y, 7) print("USE ARROWS", 88, 240, 6) end
2. Bouncing Ball
Beginner
A ball bouncing off all four walls with velocity. Demonstrates physics-style movement,
boundary collision, and circfill.
function _init() x, y = 128, 128 vx, vy = 2, 1.5 r = 6 -- ball radius col = 10 -- yellow end function _update() x += vx y += vy -- bounce off left/right walls if x < r then x = r; vx = abs(vx) sfx(0) elseif x > 256-r then x = 256-r; vx = -abs(vx) sfx(0) end -- bounce off top/bottom walls if y < r then y = r; vy = abs(vy) sfx(0) elseif y > 256-r then y = 256-r; vy = -abs(vy) sfx(0) end -- change color on bounce col = flr(rnd(14)) + 1 end function _draw() cls(0) -- trail effect: draw faded circles circ(x-vx*3, y-vy*3, r, 5) circ(x-vx*2, y-vy*2, r, 5) circfill(x, y, r, col) end
3. Parallax Starfield
Intermediate60 stars split into three depth layers, each scrolling at a different speed. Demonstrates table initialisation, modular arithmetic for wrapping, and layered rendering.
function _init() stars = {} for i = 1, 60 do add(stars, { x = rnd(256), y = rnd(256), layer = flr(rnd(3)), -- 0=far 1=mid 2=near }) end end local speeds = {0.2, 0.6, 1.5} -- pixels/frame per layer local colors = {5, 6, 7 } -- dark→light local sizes = {0, 0, 1 } -- radius (0=pixel, 1=small circ) function _update() for s in all(stars) do s.y += speeds[s.layer + 1] if s.y > 256 then s.y = 0 s.x = rnd(256) end end end function _draw() cls(0) for s in all(stars) do local l = s.layer + 1 if sizes[l] == 0 then pset(flr(s.x), flr(s.y), colors[l]) else circfill(flr(s.x), flr(s.y), sizes[l], colors[l]) end end print("PLUTO-8", 96, 120, 7) print("PARALLAX DEMO", 72, 132, 6) end
4. Snake Game
IntermediateClassic Snake with growing tail, food spawning, wall and self-collision. Shows a state machine (title / playing / game-over), grid-based movement and table manipulation.
local GRID = 8 -- tile size in pixels local W, H = 32, 32 -- grid dimensions function _init() state = "title" end function start_game() snake = {{x=16, y=16}} dir = {x=1, y=0} next_d = {x=1, y=0} score = 0 timer = 0 spawn_food() state = "play" end function spawn_food() food = {x=flr(rnd(W)), y=flr(rnd(H))} end function _update() if state == "title" then if btnp(4) then start_game() end return end if state == "over" then if btnp(4) then state = "title" end return end -- read input (don't allow 180° reverse) if btn(0) and dir.x ~= 1 then next_d={x=-1,y=0} end if btn(1) and dir.x ~= -1 then next_d={x=1,y=0} end if btn(2) and dir.y ~= 1 then next_d={x=0,y=-1} end if btn(3) and dir.y ~= -1 then next_d={x=0,y=1} end timer += 1 if timer < 6 then return end -- move every 6 ticks (5 moves/sec) timer = 0 dir = next_d -- new head position local head = snake[1] local nx = (head.x + dir.x) % W local ny = (head.y + dir.y) % H -- check self-collision for s in all(snake) do if s.x == nx and s.y == ny then sfx(1); state = "over"; return end end -- grow or trim tail local ate = (nx == food.x and ny == food.y) table.insert(snake, 1, {x=nx, y=ny}) if ate then score += 10; sfx(0); spawn_food() else table.remove(snake) end end function _draw() cls(0) if state == "title" then print("SNAKE", 104, 110, 11) print("PRESS Z", 96, 130, 7) return end -- food rectfill(food.x*GRID, food.y*GRID, GRID, GRID, 8) -- snake body for i, s in ipairs(snake) do local c = (i == 1) and 11 or 3 rectfill(s.x*GRID+1, s.y*GRID+1, GRID-2, GRID-2, c) end -- HUD print("SCORE:"..score, 2, 2, 7) if state == "over" then rectfill(70, 108, 116, 40, 0) rect( 70, 108, 116, 40, 8) print("GAME OVER", 88, 118, 8) print("PRESS Z", 96, 132, 7) end end
5. Sprite Animation & Flip
Beginner
Walk-cycle animation using sprite frames, with horizontal flipping for left/right
direction. Shows how to combine movement, timers and spr() flags.
-- Assumes sprites 1-4 are a 4-frame walk cycle local WALK_FRAMES = {1, 2, 3, 4} local ANIM_SPEED = 6 -- ticks per frame function _init() px, py = 120, 120 facing = 1 -- 1=right, -1=left anim_t = 0 anim_frame = 1 moving = false end function _update() moving = false if btn(0) then px -= 2; facing = -1; moving = true end if btn(1) then px += 2; facing = 1; moving = true end if btn(2) then py -= 2; moving = true end if btn(3) then py += 2; moving = true end -- advance animation only when moving if moving then anim_t += 1 if anim_t >= ANIM_SPEED then anim_t = 0 anim_frame = (anim_frame % #WALK_FRAMES) + 1 end else anim_frame = 1 -- idle = frame 1 anim_t = 0 end end function _draw() cls(3) -- ground rectfill(0, 200, 256, 56, 4) local sprite_n = WALK_FRAMES[anim_frame] local flip_x = (facing == -1) -- flip left spr(sprite_n, px, py, 1, 1, flip_x) print("MOVE: ARROWS", 74, 8, 7) end