@@ -0,0 +1,608 @@
---@meta
-- Generated by usagi 0.6.1. Run `usagi refresh` to update.
-- Usagi API stubs for lua-language-server.
-- Declarations only; this file is never executed by the runtime.
---Pico-8 palette, indices 0-15.
---@class Usagi.Gfx
---@field COLOR_BLACK integer 0
---@field COLOR_DARK_BLUE integer 1
---@field COLOR_DARK_PURPLE integer 2
---@field COLOR_DARK_GREEN integer 3
---@field COLOR_BROWN integer 4
---@field COLOR_DARK_GRAY integer 5
---@field COLOR_LIGHT_GRAY integer 6
---@field COLOR_WHITE integer 7
---@field COLOR_RED integer 8
---@field COLOR_ORANGE integer 9
---@field COLOR_YELLOW integer 10
---@field COLOR_GREEN integer 11
---@field COLOR_BLUE integer 12
---@field COLOR_INDIGO integer 13
---@field COLOR_PINK integer 14
---@field COLOR_PEACH integer 15
gfx = { }
---Clears the screen to the given color.
---@param color integer a gfx.COLOR_* constant
function gfx . clear ( color ) end
---Draws text at (x, y) in the given color. Uses the bundled monogram
---font at its 16px design size (a 5× 7 pixel font with 16px line height).
---@param text string string to render
---@param x number left edge in game-space pixels
---@param y number top edge in game-space pixels
---@param color integer a gfx.COLOR_* constant
function gfx . text ( text , x , y , color ) end
---Draws a rectangle outline.
---@param x number left edge in game-space pixels
---@param y number top edge in game-space pixels
---@param w number width in pixels
---@param h number height in pixels
---@param color integer a gfx.COLOR_* constant
function gfx . rect ( x , y , w , h , color ) end
---Draws a filled rectangle.
---@param x number left edge in game-space pixels
---@param y number top edge in game-space pixels
---@param w number width in pixels
---@param h number height in pixels
---@param color integer a gfx.COLOR_* constant
function gfx . rect_fill ( x , y , w , h , color ) end
---Draws a circle outline centered at (x, y).
---@param x number center x in game-space pixels
---@param y number center y in game-space pixels
---@param r number radius in pixels
---@param color integer a gfx.COLOR_* constant
function gfx . circ ( x , y , r , color ) end
---Draws a filled circle centered at (x, y).
---@param x number center x in game-space pixels
---@param y number center y in game-space pixels
---@param r number radius in pixels
---@param color integer a gfx.COLOR_* constant
function gfx . circ_fill ( x , y , r , color ) end
---Draws a line from (x1, y1) to (x2, y2).
---@param x1 number start x in game-space pixels
---@param y1 number start y in game-space pixels
---@param x2 number end x in game-space pixels
---@param y2 number end y in game-space pixels
---@param color integer a gfx.COLOR_* constant
function gfx . line ( x1 , y1 , x2 , y2 , color ) end
---Sets a single pixel.
---@param x number x in game-space pixels
---@param y number y in game-space pixels
---@param color integer a gfx.COLOR_* constant
function gfx . pixel ( x , y , color ) end
---Draws a 16× 16 sprite from the loaded sheet at (x, y). The sheet is
---`sprites.png` next to the game's main .lua; indices run left-to-right,
---top-to-bottom. Alpha-channel pixels render as transparent.
---@param index integer one-based sprite index (1 = top-left cell)
---@param x number destination left edge in game-space pixels
---@param y number destination top edge in game-space pixels
function gfx . spr ( index , x , y ) end
---Extended `spr`: draws a 16× 16 sprite with required flip flags. Same
---indexing as `gfx.spr`.
---@param index integer one-based sprite index (1 = top-left cell)
---@param x number destination left edge in game-space pixels
---@param y number destination top edge in game-space pixels
---@param flip_x boolean flip horizontally (mirror left/right) when true
---@param flip_y boolean flip vertically (mirror top/bottom) when true
function gfx . spr_ex ( index , x , y , flip_x , flip_y ) end
---Draws an arbitrary (sx, sy, sw, sh) rectangle from `sprites.png` at
---(dx, dy) at its original size. `s*` args index into the source sheet
---in pixels; `d*` args are the destination on screen.
---@param sx number source rect left edge on `sprites.png` (pixels)
---@param sy number source rect top edge on `sprites.png` (pixels)
---@param sw number source rect width in pixels
---@param sh number source rect height in pixels
---@param dx number destination left edge in game-space pixels
---@param dy number destination top edge in game-space pixels
function gfx . sspr ( sx , sy , sw , sh , dx , dy ) end
---Extended `sspr`: source rect stretched to (dw, dh) at the destination
---with required flip flags. All ten args required; write a thin
---wrapper if a particular flag combination shows up often in your
---code.
---@param sx number source rect left edge on `sprites.png` (pixels)
---@param sy number source rect top edge on `sprites.png` (pixels)
---@param sw number source rect width in pixels
---@param sh number source rect height in pixels
---@param dx number destination left edge in game-space pixels
---@param dy number destination top edge in game-space pixels
---@param dw number destination width in pixels (stretches the source)
---@param dh number destination height in pixels (stretches the source)
---@param flip_x boolean flip horizontally (mirror left/right) when true
---@param flip_y boolean flip vertically (mirror top/bottom) when true
function gfx . sspr_ex ( sx , sy , sw , sh , dx , dy , dw , dh , flip_x , flip_y ) end
---Activates a post-process fragment shader. Loads `shaders/<name>.fs`
---(and optional `<name>.vs`) and runs it as the final pass when the
---game render target is blitted to the window. Pass nil to clear.
---On web the loader prefers `<name>_es.fs` (GLSL ES 100); on desktop
---it prefers `<name>.fs` (GLSL 330). Shader source live-reloads on
---save in `usagi dev`.
---@param name string|nil shader name (file stem under `shaders/`), or nil to clear
function gfx . shader_set ( name ) end
---Sets a uniform on the active shader. The value type drives the
---uniform type: a number maps to float, a 2/3/4-length numeric table
---maps to vec2 / vec3 / vec4. Queues the write; the engine flushes
---queued uniforms once per frame before the post-process pass.
---@param name string uniform name as declared in the shader source
---@param value number|number[] float, or {x, y} / {x, y, z} / {x, y, z, w}
function gfx . shader_uniform ( name , value ) end
---@class Usagi.Sfx
sfx = { }
---Plays a sound effect by name. Names are file stems from the `sfx/`
---directory next to the game's main .lua (e.g. `sfx/jump.wav` → "jump").
---Unknown names silently no-op. Calling while already playing restarts.
---@param name string file stem of a `.wav` under `sfx/`
function sfx . play ( name ) end
---@class Usagi.Music
music = { }
---Plays a music track once and stops at the end. Names are file stems
---from the `music/` directory next to the game's main .lua (e.g.
---`music/intro.ogg` → "intro"). Recognized extensions: ogg, mp3, wav,
---flac. Stops the currently-playing track first if there is one.
---Unknown names silently no-op. Callable from `_init` so a title
---track can start the moment the window opens.
---@param name string file stem under `music/`
function music . play ( name ) end
---Plays a music track and loops it forever. Stops the currently-
---playing track first. Callable from `_init`.
---@param name string file stem under `music/`
function music . loop ( name ) end
---Stops whatever music is currently playing. No-op when nothing is.
function music . stop ( ) end
---Abstract input actions. Each is a union over keyboard keys, gamepad
---buttons, and analog-stick directions:
---
---- LEFT: arrow left, A, dpad left, left stick left
---- RIGHT: arrow right, D, dpad right, left stick right
---- UP: arrow up, W, dpad up, left stick up
---- DOWN: arrow down, S, dpad down, left stick down
---- BTN1: Z, J; gamepad south face (Xbox A, PS Cross)
---- BTN2: X, K; gamepad east face (Xbox B, PS Circle)
---- BTN3: C, L; gamepad north + west face (Xbox Y/X, PS Triangle/Square)
---
---Mouse buttons (separate from the action constants above):
---
---- MOUSE_LEFT: left mouse button
---- MOUSE_RIGHT: right mouse button
---
---Source identifiers for `input.last_source()` and the source-aware
---`input.mapping_for`:
---
---- SOURCE_KEYBOARD: "keyboard"
---- SOURCE_GAMEPAD: "gamepad"
---@class Usagi.Input
---@field LEFT integer
---@field RIGHT integer
---@field UP integer
---@field DOWN integer
---@field BTN1 integer
---@field BTN2 integer
---@field BTN3 integer
---@field MOUSE_LEFT integer
---@field MOUSE_RIGHT integer
---@field SOURCE_KEYBOARD string
---@field SOURCE_GAMEPAD string
---@field KEY_A integer
---@field KEY_B integer
---@field KEY_C integer
---@field KEY_D integer
---@field KEY_E integer
---@field KEY_F integer
---@field KEY_G integer
---@field KEY_H integer
---@field KEY_I integer
---@field KEY_J integer
---@field KEY_K integer
---@field KEY_L integer
---@field KEY_M integer
---@field KEY_N integer
---@field KEY_O integer
---@field KEY_P integer
---@field KEY_Q integer
---@field KEY_R integer
---@field KEY_S integer
---@field KEY_T integer
---@field KEY_U integer
---@field KEY_V integer
---@field KEY_W integer
---@field KEY_X integer
---@field KEY_Y integer
---@field KEY_Z integer
---@field KEY_0 integer
---@field KEY_1 integer
---@field KEY_2 integer
---@field KEY_3 integer
---@field KEY_4 integer
---@field KEY_5 integer
---@field KEY_6 integer
---@field KEY_7 integer
---@field KEY_8 integer
---@field KEY_9 integer
---@field KEY_F1 integer
---@field KEY_F2 integer
---@field KEY_F3 integer
---@field KEY_F4 integer
---@field KEY_F5 integer
---@field KEY_F6 integer
---@field KEY_F7 integer
---@field KEY_F8 integer
---@field KEY_F9 integer
---@field KEY_F10 integer
---@field KEY_F11 integer
---@field KEY_F12 integer
---@field KEY_SPACE integer
---@field KEY_ENTER integer
---@field KEY_ESCAPE integer
---@field KEY_TAB integer
---@field KEY_BACKSPACE integer
---@field KEY_DELETE integer
---@field KEY_LEFT integer
---@field KEY_RIGHT integer
---@field KEY_UP integer
---@field KEY_DOWN integer
---@field KEY_LSHIFT integer
---@field KEY_RSHIFT integer
---@field KEY_LCTRL integer
---@field KEY_RCTRL integer
---@field KEY_LALT integer
---@field KEY_RALT integer
---@field KEY_BACKTICK integer
---@field KEY_MINUS integer
---@field KEY_EQUAL integer
---@field KEY_LBRACKET integer
---@field KEY_RBRACKET integer
---@field KEY_BACKSLASH integer
---@field KEY_SEMICOLON integer
---@field KEY_APOSTROPHE integer
---@field KEY_COMMA integer
---@field KEY_PERIOD integer
---@field KEY_SLASH integer
input = { }
---Returns true the frame any source bound to `action` first went down.
---@param action integer one of input.LEFT / RIGHT / UP / DOWN / BTN1 / BTN2 / BTN3
---@return boolean
function input . pressed ( action ) end
---Returns true while any source bound to `action` is held.
---@param action integer one of input.LEFT / RIGHT / UP / DOWN / BTN1 / BTN2 / BTN3
---@return boolean
function input . held ( action ) end
---Returns true the frame any source bound to `action` first went up
---(transitioned from held to released). Mirrors `input.pressed` for the
---release edge.
---@param action integer one of input.LEFT / RIGHT / UP / DOWN / BTN1 / BTN2 / BTN3
---@return boolean
function input . released ( action ) end
---Label of the active input source's primary binding for `action` (e.g.
---"Z" on keyboard, "Pad-A" on gamepad). Honors any keymap remap the
---player set via the pause menu's Configure Keys flow. Useful for
---rendering contextual control prompts. Returns `nil` for unknown
---actions or when the active source has no binding for `action`.
---@param action integer one of input.LEFT / RIGHT / UP / DOWN / BTN1 / BTN2 / BTN3
---@return string?
function input . mapping_for ( action ) end
---The input source that most recently fired any bound action. Returns
---`input.SOURCE_KEYBOARD` ("keyboard") or `input.SOURCE_GAMEPAD`
---("gamepad"). Switches only when a *bound* input fires, so menu keys
---and idle activity don't flip it.
---@return string matches one of input.SOURCE_KEYBOARD / input.SOURCE_GAMEPAD
function input . last_source ( ) end
---Cursor position in game-space pixels (so it lines up with `gfx.*`
---coords regardless of window size or pixel-perfect scaling). Returns
---two values: `x, y`. When the cursor sits over the letterbox bars,
---the values fall outside `0..usagi.GAME_W` / `0..usagi.GAME_H` —
---bounds-check before treating them as in-game coords.
---@return integer x game-space x in pixels
---@return integer y game-space y in pixels
function input . mouse ( ) end
---Returns true while the given mouse button is held.
---@param button integer one of input.MOUSE_LEFT / input.MOUSE_RIGHT
---@return boolean
function input . mouse_held ( button ) end
---Returns true the frame the given mouse button first went down.
---@param button integer one of input.MOUSE_LEFT / input.MOUSE_RIGHT
---@return boolean
function input . mouse_pressed ( button ) end
---Returns true the frame the given mouse button first went up
---(transitioned from held to released).
---@param button integer one of input.MOUSE_LEFT / input.MOUSE_RIGHT
---@return boolean
function input . mouse_released ( button ) end
---Returns true while the given keyboard key is held.
---
---Direct keyboard reads bypass the keymap override and gamepad
---bindings — prefer `input.held(action)` for game actions players
---should be able to remap or play with a controller. Use this for dev
---hotkeys (toggling debug overlays, F-key shortcuts) and for
---keyboard-and-mouse-only games.
---@param key integer one of the input.KEY_* constants
---@return boolean
function input . key_held ( key ) end
---Returns true the frame the given keyboard key first went down. See
---`input.key_held` for the bypass-the-keymap caveat.
---@param key integer one of the input.KEY_* constants
---@return boolean
function input . key_pressed ( key ) end
---Returns true the frame the given keyboard key first went up
---(transitioned from held to released). See `input.key_held` for the
---bypass-the-keymap caveat.
---@param key integer one of the input.KEY_* constants
---@return boolean
function input . key_released ( key ) end
---Show or hide the OS cursor over the game window. Persists until
---changed. Callable from `_init` so games can hide the cursor before
---the first frame draws (e.g. when rendering a custom in-game cursor).
---@param visible boolean true to show, false to hide
function input . set_mouse_visible ( visible ) end
---Returns true when the OS cursor is currently shown over the window.
---Reflects the latest `input.set_mouse_visible` call synchronously, so
---it's safe to use as part of a toggle:
---`input.set_mouse_visible(not input.mouse_visible())`.
---@return boolean
function input . mouse_visible ( ) end
---Engine-level info. The per-domain APIs (`gfx`, `input`) are top-level
---globals, not fields on this table.
---@class Usagi
---@field GAME_W number game render width in pixels
---@field GAME_H number game render height in pixels
---@field SPRITE_SIZE integer side length, in pixels, of one cell in `sprites.png` (drives `gfx.spr` indexing)
---@field IS_DEV boolean true under `usagi dev`; false for `usagi run` and compiled binaries
---@field elapsed number wall-clock seconds since session start; updated once per frame before _update
usagi = { }
---Measures `text` in the bundled font and returns its rendered size
---in pixels. Returns two values: `width, height`. Available from any
---callback (`_init`, `_update`, `_draw`) — useful for pre-computing
---layout once in `_init` and reusing the result every frame.
---@param text string string to measure
---@return integer width pixel width
---@return integer height pixel height (equals the font's line height)
function usagi . measure_text ( text ) end
---Persist a Lua table as JSON. Saves are per-game, namespaced by
---`game_id` from `_config()`. One file per game; nest your own
---structure inside (settings, run state, unlocks).
---@param t table table to serialize. functions, userdata, NaN, and cycles error
function usagi . save ( t ) end
---Read the persisted save table back. Returns `nil` on first run
---(no save file). Idiomatic call: `state = usagi.load() or { ... defaults ... }`.
---@return table?
function usagi . load ( ) end
---Config table returned by `_config()`. All fields optional except
---`game_id`, which is only required if you call `usagi.save` /
---`usagi.load`. Missing fields fall back to engine defaults.
---@class Usagi.Config
---@field name? string display name. Window title, macOS .app bundle directory, and (slugged) archive/binary names on `usagi export` (default: project directory name)
---@field pixel_perfect? boolean false (default) = any scale that fits the window while preserving aspect ratio; true = integer scale only with letterbox bars
---@field game_id? string reverse-DNS identifier (e.g. "com.you.mygame"), required for save/load
---@field icon? integer 1-based tile index into sprites.png to use as the window icon (same indexing as gfx.spr); omit for the default Usagi bunny
---@field game_width? number game render width in pixels (default 320). Tested range 160..640
---@field game_height? number game render height in pixels (default 180). Tested range 90..360
---@field sprite_size? integer side length, in pixels, of one cell in sprites.png (default 16). Drives gfx.spr indexing, the tilepicker tool's grid, and the window-icon slicer. sprites.png must be a multiple of this value on both axes.
---Optional. Returns engine config read once before the window opens.
---Omit if the defaults are fine.
---@return Usagi.Config?
function _config ( ) end
---Called once when the game starts. Use for loading assets and initializing state.
function _init ( ) end
---Called every frame to update game state. Runs before _draw.
---@param dt number delta-time: seconds since last frame
function _update ( dt ) end
---Called every frame to render. Runs after _update.
---@param dt number delta-time: seconds since last frame
function _draw ( dt ) end
---@class Usagi.Vec2
---@field x number
---@field y number
---@class Usagi.Rect
---@field x number
---@field y number
---@field w number
---@field h number
---@class Usagi.Circ
---@field x number
---@field y number
---@field r number
---Drop-in math/geometry helpers. Pure Lua, no engine state. Source
---lives in `runtime/util.lua` — read it for full implementations or
---fork it if you want different semantics.
---@class Usagi.Util
util = { }
---Clamps `v` into `[lo, hi]`.
---@param v number
---@param lo number
---@param hi number
---@return number
function util . clamp ( v , lo , hi ) end
---Returns -1, 0, or 1 according to the sign of `v`.
---@param v number
---@return integer
function util . sign ( v ) end
---Half-up rounding to the nearest integer. Pixel snapping is the
---driving use case in 2D pixel-art games.
---@param v number
---@return integer
function util . round ( v ) end
---Moves `current` toward `target` by at most `max_delta`, never
---overshooting. Per-frame smoothing primitive — pass a delta
---scaled by `dt` for frame-rate independence.
---@param current number
---@param target number
---@param max_delta number
---@return number
function util . approach ( current , target , max_delta ) end
---Linear interpolation. `t = 0` returns `a`, `t = 1` returns `b`.
---Values of `t` outside `[0, 1]` extrapolate (no clamping).
---@param a number
---@param b number
---@param t number
---@return number
function util . lerp ( a , b , t ) end
---Wraps `v` into `[lo, hi)`. Useful for cyclic values like angles or
---looped indexing. Works for negative `v`: `util.wrap(-1, 0, 4) == 3`.
---@param v number
---@param lo number
---@param hi number
---@return number
function util . wrap ( v , lo , hi ) end
---Boolean from time. Toggles `hz` times per second — the on/off
---interval is `1/hz` seconds. For invincibility flicker, UI blinks,
---low-health warnings.
---@param t number seconds
---@param hz number toggles per second
---@return boolean
function util . flash ( t , hz ) end
---Normalizes a `{x, y}` vector to unit length. Returns a new table;
---the input is unchanged. A zero vector returns `{x = 0, y = 0}`.
---@param v Usagi.Vec2
---@return Usagi.Vec2
function util . vec_normalize ( v ) end
---Distance between two `{x, y}` points.
---@param a Usagi.Vec2
---@param b Usagi.Vec2
---@return number
function util . vec_dist ( a , b ) end
---Squared distance between two `{x, y}` points. Cheaper than
---`vec_dist` (skips the sqrt); use for "is X closer than Y?" by
---comparing against `r * r`.
---@param a Usagi.Vec2
---@param b Usagi.Vec2
---@return number
function util . vec_dist_sq ( a , b ) end
---Builds a vector at `angle` (radians) with magnitude `len`. `len`
---defaults to 1 for a unit vector. Pair with `math.atan(dy, dx)` to
---convert any direction into a velocity.
---@param angle number radians
---@param len? number magnitude (default 1)
---@return Usagi.Vec2
function util . vec_from_angle ( angle , len ) end
---True when the `{x, y}` point is inside the rect `{x, y, w, h}`.
---Half-open: left/top edges are inside, right/bottom edges are
---outside. Matches typical sprite-rect hit testing.
---@param p Usagi.Vec2
---@param r Usagi.Rect
---@return boolean
function util . point_in_rect ( p , r ) end
---True when the `{x, y}` point is strictly inside the circle
---`{x, y, r}`. Points on the boundary are considered outside.
---@param p Usagi.Vec2
---@param c Usagi.Circ
---@return boolean
function util . point_in_circ ( p , c ) end
---True when the two AABBs share interior area. Edge-adjacent rects
---are considered non-overlapping.
---@param a Usagi.Rect
---@param b Usagi.Rect
---@return boolean
function util . rect_overlap ( a , b ) end
---True when the two circles overlap. Tangent circles are
---considered non-overlapping.
---@param a Usagi.Circ
---@param b Usagi.Circ
---@return boolean
function util . circ_overlap ( a , b ) end
---True when a circle and a rect overlap. Uses the closest-point
---method: clamp the circle center to the rect, test distance.
---@param c Usagi.Circ
---@param r Usagi.Rect
---@return boolean
function util . circ_rect_overlap ( c , r ) end
---Engine-level juice primitives: hitstop, screen shake, flash, and
---slow-motion. Each call sets per-session state that decays once per
---frame. Stacking rule across all four: longer duration wins; for
---the magnitude param, the latest call wins. Spam-calling is safe.
effect = { }
---Freezes the game's `_update` loop for `time` seconds. `_draw` keeps
---running so the world stays on-screen. The classic juice trick for
---weighty hits: pair with `effect.screen_shake` and `effect.flash` on
---impact. If a longer hitstop is already in flight, this call is a
---no-op (longer wins).
---@param time number seconds to freeze update
function effect . hitstop ( time ) end
---Shakes the rendered view for `time` seconds with up to `intensity`
---game-pixel offset. Magnitude decays linearly to zero across the
---duration. The shake is applied to the RT-to-screen blit, so
---overlays drawn outside the world (error, REC indicator) stay
---stable.
---@param time number seconds to shake
---@param intensity number maximum offset in game pixels (try 2-6)
function effect . screen_shake ( time , intensity ) end
---Flashes a full-screen overlay of palette color `color` over the
---rendered view for `time` seconds. Alpha decays linearly from
---opaque to transparent. White on hits, red on damage, etc.
---@param time number seconds the flash is visible
---@param color integer a gfx.COLOR_* constant
function effect . flash ( time , color ) end
---Scales the `dt` passed to `_update` for `time` seconds. `scale=0.5`
---is half-speed; `scale=0` freezes update (use `effect.hitstop` for
---that explicitly); `scale>1` plays faster. Wall-clock decay is
---unaffected; the slow_mo timer itself counts down at real time.
---@param time number seconds the scale is applied
---@param scale number dt multiplier; 0..1 for slow, >1 for fast
function effect . slow_mo ( time , scale ) end