Files
tactility_apps/Apps/LuaGame/README.md
Adolfo 1a1e391a14 docs(LuaGame): update README with audio, FPS 17.5, Pico compatibility
- Document SfxEngine audio mapping
- Document 4.5x ball speed, 17.5 FPS after direct FB font
- Document Pico API shim (renderer, game, INPUT) and 17 games portability
- Tested Pong runs with no Lua errors
2026-07-31 12:57:12 -04:00

73 lines
4.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# LuaGame - Lua Interpreter Game Engine
External ELF app that runs Lua games on Tactility OS (ES3C35P 320x480 tested on 192.168.68.107).
## How it works
- Embeds Lua 5.4.7 source (no external dependency, avoids missing symbol issues)
- Lua init + game loop run in dedicated 16K stack FreeRTOS task to avoid GUI task (4096 bytes) stack overflow
- Game framebuffer: 240x240 RGB565 in PSRAM, rendered via LVGL canvas (`lv_canvas_set_buffer` + `lv_obj_invalidate` with `tt_lvgl_lock`)
- Direct framebuffer text using 8x8 bitmap font (`font8x8.h`) – 17+ FPS vs 15 FPS with LVGL labels
- **Sys API** (original Tactility breakout.lua):
- `sys.log(msg)`
- `sys.clear(hexColor)`
- `sys.print(x,y,text,hexColor)` – direct FB via `draw_text8`
- `sys.rect(x,y,w,h,hexColor,filled)` – border or filled
- `sys.circle(x,y,r,hexColor,filled)` – midpoint + filled scan
- `sys.line(x0,y0,x1,y1,hexColor)`
- `sys.touch() -> pressed, tx, ty` (touch mapped to 240 game space)
- `sys.tone(note, duration, waveform, volume)` → SfxEngine `playNote`
- `sys.sfx(name)` → SfxEngine `play(SfxId)` mapping: confirm, coin, hurt, gameover, levelup, brickhit, etc.
- **Pico API** compatibility (from `/Users/adolforeyna/Projects/pico-bare-metal/Adolfo/basic1/games/lua_examples`):
- `game.width()`, `height()`, `set_frame_updates(bool)`, `exit()`, `game.vars` persistent table
- `renderer.clear(white)`, `pixel(x,y,on)`, `line(x0,y0,x1,y1,on,width)`, `rect(x,y,w,h,on,filled)`, `circle(x,y,r,on,filled)`, `triangle(x0,y0,x1,y1,x2,y2,on,filled)`, `text(x,y,txt,on)`, `text_scaled(x,y,txt,on,scale)` (scale 1-4)
- `INPUT` constants: `NONE=0, TOUCH_DOWN=1, TOUCH_MOVE=2, TOUCH_UP=3, BUTTON_0=4, BUTTON_1=5, FRAME_TICK=6, GESTURE=7`
- Event system: generates `TOUCH_DOWN/MOVE/UP` from touch state + `FRAME_TICK` every frame, calls `update(event)` returning bool redraw
- Detection: if source contains `renderer.` → Pico mode, else sys mode
- Embedded games:
- `embedded_breakout_lua_src` – fast breakout (ball 4.5 vs 2, paddle 0.25 spin) – default
- `pico_games.h` auto-generated with 17 games: 2048, air_hockey, asteroids, ball, breakout, counter, flappy_bird, lunar_lander, memory_match, pacman, pong, simon_says, snake, solitaire, tetris, tic_tac_toe – tested Pong runs at 17.5 FPS
- File loading: PSRAM buffer + `luaL_loadbuffer` to avoid `luaL_loadfile` stack issues, supports SD paths `/sdcard/lua/*.lua`
## Symbol fixes
Previous missing: `clearerr`, `clock`, `getenv`, `gmtime`, `setlocale`, `setvbuf`, `tmpfile`, `tmpnam`, `ungetc`, `lv_canvas_get_draw_buf`, `lv_draw_buf_invalidate_cache`, `lv_image_cache_drop`.
Fixed by local stubs + avoiding unexported APIs, only `lv_canvas_create`, `lv_canvas_set_buffer`, `lv_obj_invalidate`, `tt_lvgl_lock/unlock`.
## Performance
- Ball speed: 2 → 4.5 (2.25x faster), configurable in embedded string
- FPS: 15 → 17.5 FPS after direct FB text + dedicated game loop task
- Memory: internal low ~2-3KB (PSRAM used for FB and Lua heap), stable, no crash 20s+
## Build / Install
```bash
cd /Users/adolforeyna/Projects/Tactility/apps
unset PYTHONPATH; unset PYTHONHOME
export IDF_PYTHON_ENV_PATH=/Users/adolforeyna/.espressif/python_env/idf5.3_py3.9_env
source /Users/adolforeyna/esp/esp-idf/export.sh
export TACTILITY_SDK_PATH=/Users/adolforeyna/Projects/Tactility/firmware/release/TactilitySDK
export ESP_IDF_VERSION=5.5
python tactility.py Apps/LuaGame build esp32s3 --local-sdk
curl -X PUT http://192.168.68.107/api/apps/install -F "file=@Apps/LuaGame/build/LuaGame.app"
curl -X POST "http://192.168.68.107/api/apps/run?id=one.tactility.luagame"
```
## Porting Pico Games
Yes – all 17 examples from `pico-bare-metal/Adolfo/basic1/games/lua_examples` use:
- `game.vars` state machine
- `renderer.*` monochrome API (boolean on/off → mapped to white/black RGB565)
- `INPUT.TOUCH_*` + `FRAME_TICK`
Our engine now implements compatibility shim in C (see `l_renderer_*`, `l_game_*`, INPUT table). Pong tested:
```
[LuaGame] using Pico test game: Pong (7538 bytes)
Pong initialized
FPS 17.5
```
Other games (snake, tetris, 2048, etc.) should work same – they are ~50-880 lines, no file I/O, pure math/table. To add selector UI, list `pico_games[]` via LVGL list and load selected `src`.
## TODO
- Game selector UI (menu_wrapper + game_wrapper, hide/show)
- Copy pico examples to SD via USB MSC or bundle selector
- Audio mapping for Pico games (currently sys.sfx only, could map to renderer events)
- Scale canvas to full 320x480 or dynamic `game.width/height`
- Fix internal memory low warnings (reduce SfxEngine voices or Lua heap)