Tangy exposes a small, intentional Lua 5.4 surface. Colon and dot call styles both work
(sprite:load(...) or sprite.load(...)).
Lifecycle & timing
The entry script (main.lua) runs as a coroutine so wait works at
top level. There is no engine-provided update or draw callback.
API
Description
wait(ms)
Yield the current coroutine for at least ms milliseconds.
engine:spawn(fn)
Start fn as a new coroutine.
engine:yield()
Pause until the next frame.
engine:time()
Monotonic milliseconds since the scheduler started.
engine:spawn(function()
while true do
-- per-frame game logic
engine:yield()
end
end)
Input
API
Description
input.button_pressed:connect(fn)
Register a press handler: function(button, isGamepad).
input.button_released:connect(fn)
Register a release handler with the same signature.
On desktop (Linux today), handlers receive SDL keyboard names (Left,
Right, Space, …) with isGamepad=false — Tangy is meant
for making desktop games with keyboard input as well as handheld titles. On the Nintendo 3DS
family, buttons are A, B, X, Y,
L, R, ZL, ZR, Start,
Select, DPadLeft, DPadRight, DPadUp,
DPadDown with isGamepad=true. Handlers are spawned as coroutines when
they fire — use engine:spawn if you need wait from nested logic
patterns you control yourself.
Sprites — sprite
Max loaded sprites defaults to 1024 (shared graphics budget with unique tileset tile types).
Max sprite size is 64×64. Frame indices are 1-based.
API
Description
id = sprite:load(path)
Load a .tngspr; returns slot id.
ok = sprite:unload(id)
Free a sprite slot.
x, y = sprite:getpos(id)
Pixel position.
sprite:setpos(id, x, y)
Set position (fractional values round to pixels).
sprite:flip(id, axis)
Toggle flip; axis1 = X, 2 = Y.
flipX, flipY = sprite:getflip(id)
Current flip state (booleans).
sprite:setframe(id, frame)
Set animation frame (1-based).
used, max = sprite:slots()
Occupied loaded-sprite count and max slots.
Scene / tiles — scene
Four layers (1 = front, 4 = back). Tiles are 16×16.
API
Description
scene:load(path)
Load a .tngscn (replaces current scene; sprites untouched).
scene:unload([path])
Unload the scene; optional path string.
scene:reload()
Restore pristine tile data after runtime edits.
scene:set_tile(tileId, tx, ty [, layer])
Set a cell; layer defaults to 1; tile 0 = empty.
tileId = scene:get_tile(tx, ty [, layer])
Read a cell; layer defaults to 1.
tx, ty = scene:spritepos_to_tilepos(x, y)
Pixel → tile coords (uses layer-1 scroll).
scene:setscroll(x, y [, layer])
Pixel camera / parallax scroll; layer 1–4, default 1.
Palette — palette
API
Description
palette:load(path)
Load a .tngpal (15-bit, ≤256 colours). May swap anytime.
Screen — screen
API
Description
screen:fill(palIndex)
Background clear colour = palette index 0–255.
Effects — effect
API
Description
effect:pixelate(amount)
SNES-style mosaic; amount 1–4 (effect id 1).
effect:colourfade(colourIndex, durationMs)
Fade toward a palette colour over milliseconds (effect id 2).
effect:clear([id])
Clear all effects, or one by id (1 = pixelate, 2 = colourfade).
Audio — sound
Up to 12 concurrent OGG streams.
API
Description
id = sound:play(path [, loop])
Stream an OGG; optional loop; returns voice id 1–12.