# Lua Game API Documentation This document describes the API available to Lua game scripts on the Pico game console. ## Script Structure Every Lua game must define three functions: ```lua function init() -- Initialize game state end function update(event) -- Process input and update game logic -- Return true if redraw needed, false otherwise return needs_redraw end function draw() -- Render the game to screen end ``` ## Metadata Comments Add metadata at the top of your script: ```lua -- NAME: My Awesome Game -- DESC: A fun game about squares ``` ## Global Tables ### `game` - Game State and Info - `game.width()` - Get display width in pixels - `game.height()` - Get display height in pixels - `game.exit()` - Request exit to game launcher - `game.vars` - Table for persistent state variables Example: ```lua function init() game.vars.score = 0 game.vars.player_x = 100 game.vars.state = 0 end ``` ### `renderer` - Drawing Functions All coordinates are in pixels. Color is boolean: `true` = black/on, `false` = white/off. #### Basic Shapes - `renderer.clear(white)` - Clear screen to white (true) or black (false) - `renderer.pixel(x, y, on)` - Set single pixel - `renderer.line(x0, y0, x1, y1, on, width)` - Draw line (width optional, default 1) - `renderer.rect(x, y, w, h, on, filled)` - Draw rectangle (filled optional, default false) - `renderer.circle(x, y, radius, on, filled)` - Draw circle (filled optional, default false) - `renderer.triangle(x0, y0, x1, y1, x2, y2, on, filled)` - Draw triangle #### Text - `renderer.text(x, y, text, on)` - Draw text string Example: ```lua function draw() renderer.clear(false) -- Clear to black renderer.rect(50, 50, 100, 80, true, true) -- Filled white rectangle renderer.circle(100, 100, 30, true, false) -- White circle outline renderer.text(10, 10, "Score: " .. tostring(game.vars.score), true) end ``` ### `INPUT` - Input Event Types Constants for checking `event.type`: - `INPUT.NONE` - No input - `INPUT.TOUCH_DOWN` - Touch/click started - `INPUT.TOUCH_MOVE` - Touch/drag in progress - `INPUT.TOUCH_UP` - Touch/click released - `INPUT.BUTTON_0` - Physical button 0 pressed - `INPUT.BUTTON_1` - Physical button 1 pressed - `INPUT.GESTURE` - Gesture detected ## Input Event Structure The `event` parameter passed to `update()` has these fields: - `event.type` - Event type (see INPUT constants) - `event.x` - X coordinate (for touch events) - `event.y` - Y coordinate (for touch events) - `event.button_id` - Button identifier (for button events) - `event.valid` - Boolean, true if event is valid Example: ```lua function update(event) if event.type == INPUT.TOUCH_DOWN then print("Touch at: " .. event.x .. ", " .. event.y) game.vars.last_touch_x = event.x game.vars.last_touch_y = event.y return true -- Request redraw end return false end ``` ## State Machine Pattern Use `game.vars` to implement state machines: ```lua local STATE_MENU = 0 local STATE_PLAYING = 1 local STATE_GAME_OVER = 2 function init() game.vars.state = STATE_MENU end function update(event) if game.vars.state == STATE_MENU then -- Handle menu input if event.type == INPUT.TOUCH_DOWN then game.vars.state = STATE_PLAYING return true end elseif game.vars.state == STATE_PLAYING then -- Handle gameplay input elseif game.vars.state == STATE_GAME_OVER then -- Handle game over screen end return false end function draw() if game.vars.state == STATE_MENU then -- Draw menu elseif game.vars.state == STATE_PLAYING then -- Draw game elseif game.vars.state == STATE_GAME_OVER then -- Draw game over screen end end ``` ## Standard Lua Libraries Available libraries: - `math` - Math functions (`math.sin`, `math.random`, etc.) - `string` - String manipulation - `table` - Table operations (`table.insert`, `table.remove`, etc.) - `coroutine` - Coroutines for advanced flow control **Not available** (embedded environment): - `io` - File I/O (use SD card APIs in C++ if needed) - `os` - Operating system functions - `debug` - Debugging functions ## Tips and Best Practices 1. **Keep it Simple** - Lua is slower than C++. Keep game logic simple for smooth performance. 2. **Use Local Variables** - Local variables are faster than globals: ```lua local function move_player() -- Local function local speed = 5 -- Local variable game.vars.player_x = game.vars.player_x + speed end ``` 3. **Minimize Allocations** - Reuse tables instead of creating new ones: ```lua -- Good: Reuse existing table game.vars.snake[1].x = new_x -- Bad: Creates garbage game.vars.snake[1] = {x = new_x, y = new_y} ``` 4. **Efficient Drawing** - Only redraw when needed. Return `false` from `update()` if nothing changed. 5. **Frame Limiting** - For animation, use frame counters: ```lua function update(event) game.vars.frame = (game.vars.frame or 0) + 1 if game.vars.frame % 5 == 0 then -- Every 5 frames -- Update animation return true end return false end ``` ## Example: Complete Minimal Game ```lua -- NAME: Click Counter -- DESC: Count your clicks function init() game.vars.count = 0 end function update(event) if event.type == INPUT.TOUCH_DOWN then game.vars.count = game.vars.count + 1 return true end return false end function draw() renderer.clear(false) local text = "Clicks: " .. tostring(game.vars.count) renderer.text(20, 20, text, true) end ``` ## Deployment 1. Save your `.lua` file to SD card in `/games/` directory 2. Eject SD card and insert into Pico console 3. Power on - your game will appear in the launcher menu 4. Select and play! No recompilation needed - edit scripts directly on SD card for rapid iteration.