-
Notifications
You must be signed in to change notification settings - Fork 34
Releases: brettchalupa/usagi
v1.1.1
5d61d84 A patch-level release specifically focused on improving web performance.
Includes a couple of smaller additions that were already done but not
worth of a minor bump.
Use usagi update to get the latest version or update through your package
manager. Then usagi refresh in your projects to get the latest docs.
Features:
usagi font bakegained five new script blocks, all included in
--scripts all:box-drawing(alias:box) for Box Drawing (U+2500–U+257F)
and Block Elements (U+2580–U+259F);arrowsfor U+2190–U+21FF;math(alias:
math-ops) for U+2200–U+22FF;geometric(alias:shapes) for
U+25A0–U+25FF; andsymbols(alias:misc-symbols) for U+2600–U+26FF. Box
drawing was the motivating gap. Fonts that lack these glyphs are unaffected;
the cmap filter drops the codepoints they don't cover. To keep an atlas small,
subtract the blocks you don't need, e.g.--scripts all,-symbols,-math. See
https://codeberg.org/brettchalupa/usagi/issues/16- Added support for the
?verbose=1query param to web builds to get diagnostic
logging to the console for debugging web build performance.
Fixes:
- Added
gfx.COLOR_TRUE_WHITEto meta Lua stubs/comments as the wrong white was
being used. - Improved web performance by only copying screen pixels from GPU to CPU for
games that callgfx.get_px, that way all games don't have to pay that cost.
This operation is seemingly slow on web. Showing about a 10% improvement in
performance from testing. See
https://codeberg.org/brettchalupa/usagi/issues/19
Assets 13
v1.1.0
7ea71ba Use usagi update to get the latest version or download below. Be sure to run
usagi refresh in your projects to get the latest docs and completion updates!
Features:
- New
usagi loveify <src> <dst>subcommand: one-time port of an Usagi project
to a Love2D 11.5 project. Walks the source tree, rewrites compound-assignment
operators (x += 1→x = x + (1)) for LuaJIT compat, copies all assets
verbatim, and drops in the Love shim runtime (usagi_shim.lua+conf.lua)
plus the bundled monogram font when the source has no customfont.png.
Refuses to overwrite an existing destination. Intended as a graduation path
when a project needs iOS / Android, more action buttons, more robust APIs, or
other Love-only features. See the new "Graduating to Love2D" section in
README.md for the workflow and what's intentionally not carried over (pause
menu, input remapping, shader hooks, hot reload, FPS overlay). - Linux aarch64 is now a published export target. Released as
usagi-<ver>-linux-aarch64.tar.gzand produced by
usagi export --target linux-aarch64(also included in--target all).
Covers Raspberry Pi, ARM Linux handhelds, ARM SBCs, and ARM Linux VMs.
#270 usagi export --target hostfuses against the running binary regardless of OS
or architecture. This lets devs on platforms outside the published-template
set (e.g., macOS Intel, FreeBSD) build the engine from source and export for
themselves. Output filename is<slug>-<os>-<arch>.zip. On unsupported hosts,
the default--target allalso produces this zip alongside the published
builds, so the dev doesn't have to know about the flag. See
Building for unsupported platforms
in the README. #273- Lua's standard
debuglibrary is now available in user code. Use
debug.getinfo/debug.tracebackfor logger line numbers, and embed
step-debuggers like debugger.lua. Note that this exposes the full library,
includingdebug.setlocal/debug.setupvalue/debug.sethook. Those can
corrupt the VM if misused, so treat them with care.
#267 usagi font bakegained a--scriptsflag for picking which Unicode blocks
to include. Pass a comma-separated list of names, withall(default) and
noneas special values and a-prefix for subtraction. Known scripts:
latin,latin-ext,greek,cyrillic,punct,cjk-punct,hiragana,
katakana,hangul(alias:korean),cjk(alias:han),halfwidth.
Examples:--scripts all,-cjkto drop Han ideographs, or
--scripts latin,koreanfor a Korean-only atlas. The--no-cjkflag is now
deprecated and prints a warning; it stays as an alias for--scripts all,-cjk
and will be removed in a future major release.
#287
Fixes:
meta/usagi.lua(the LSP type stubs) now declaresgfx.COLOR_TRUE_WHITE. The
constant has always existed at runtime (slot0, pure white), but the stub
omitted it, so editors flaggedgfx.COLOR_TRUE_WHITEas undefined. The stub's
palette docstring also wrongly claimed slot0renders as a magenta sentinel;
it resolves to true white, and only indices above the active palette's length
render as magenta.- Added missing
util.remapfunction to bundled type definitions in
meta/usagi.lua. usagiCLI output now renders colorized in Windowscmd.exe. The colorized
[usagi]log prefix relies on ANSI escape sequences; modern Windows 10+
conhost understands them but only after a process opts in via
SetConsoleMode. Windows Terminal and PowerShell inherit the opt-in from the
parent process, but barecmd.exedoes not, so previously the sequences
printed as raw bytes ([32m[usagi][0m ...). Usagi now opts in once at
startup; on truly pre-Win10 hosts where the opt-in fails, color is suppressed
and the plain[usagi]prefix path takes over.
#286usagi font bakenow includes Hangul (Korean) and Latin Extended Additional
(Vietnamese precomposed forms) by default. Previously these blocks were
excluded, so even a font with full Korean or Vietnamese coverage produced an
atlas where every Hangul or Vietnamese codepoint rendered as?. The
examples/custom_fontdemo now includes a Korean line to verify coverage end
to end. #287- Calling
usagi.read_jsonorusagi.read_textat the top ofmain.luano
longer breaksusagi toolsandusagi export; see
#264 gfx.text_excalled with 6 args (missing the requiredalphaintroduced in
v1.0.0) no longer aborts the process on Windows; the error surfaces on the
in-game overlay like other malformed calls. As part of the fix, short-arg
calls to any wrapped engine API now report the missing argument by index ("bad
argument #N to '...' (T expected, got nil)") rather than a confusing "bad
argument #1 to 'type'" message.
#259- Type annotation for
_config()table to help with autocomplete; see
#255 sfx.play(name)called repeatedly no longer cuts off the playing copy. Each
sfx now has a pool of 8 voices that overlap; the 9th simultaneous play steals
the oldest. #258usagi toolsUI now scales when the window is resized. Renders to a 1280x720
canvas and blits scaled (with letterbox bars) to fit any window size. Launches
at the largest integer canvas multiple that fits the current monitor.
#269- Right clicking in web exports now works properly and does not show the
browser's right click menu. See
https://codeberg.org/brettchalupa/usagi/issues/13
Assets 13
v1.0.0
4119ce2 v1.0.0 of Usagi Engine is here! With it comes a promise of no breaking changes
until v2 (if that ever happens). 🐰 🎉
v1.0.0 comes with a lot of nice additions based on feedback from people making
their games. And some critical bug fixes and improvements.
Install Usagi v1.0.0:
- Use
usagi updateif you already have it installed; thenusagi refreshin your project(s) - Use the install script at https://usagiengine.com
- Download for your operating system below
Breaking:
- Pixel API renamed for consistency with the other shorthand primitives (
rect,
circ,tri,spr, ...). The writer is nowgfx.px(x, y, color), the
screen-pixel reader isgfx.get_px(x, y), and the sprite-pixel reader is
gfx.get_spr_px(index, x, y). The old names,gfx.pixel,gfx.px(x, y)
(two-arg reader), andgfx.spr_px, are gone. Find and replace in your code:
gfx.pixel→gfx.px,gfx.px(x, y)→gfx.get_px(x, y),gfx.spr_px→
gfx.get_spr_px. See #215 - Palette slot
0now resolves to true white (COLOR_TRUE_WHITE) instead of
the magenta out-of-range sentinel. Negative indices and indices past the
active palette's length still render as magenta, so the "obvious unknown
color" indicator survives for the common typo cases. gfx.text_exgained a required trailingalpha(0..1) param for parity
withgfx.spr_ex/gfx.sspr_ex. Pass1.0to keep the old behavior. The
simplegfx.textsignature is unchanged.
Features:
- New
usagi.read_json(path)andusagi.read_text(path)for loading arbitrary
game data (level layouts, dialog scripts, tuning configs) from a project-level
data/directory. Paths are forward-slash relative todata/, nested subdirs
supported (usagi.read_json("levels/01.json")). The wholedata/tree is
bundled byusagi export, so the same call resolves identically in dev and
shipped builds. Hot reload: any save to a data file pokes the same
script-reload path as a.luasave, so top-level
local levels = usagi.read_json("levels.json")picks up new bytes without F5.
Newexamples/level_from_jsonandexamples/level_from_csv(the latter shows
theread_text+string.gmatchpattern for simple CSV grids, since the
engine doesn't ship a CSV parser).
See #218 - New
usagi.to_json(t)returns a Lua table as a pretty-printed JSON string.
Shares the shape validator withusagi.save, so keys must be all strings or a
dense1..ninteger array (functions, userdata, NaN, and cycles still error).
Useful for devtools, structured stdout logs, and any other place you want JSON
without writing to the save file. Seeexamples/to_json.lua. - New
gfx.tri(x1, y1, x2, y2, x3, y3, color)and
gfx.tri_fill(x1, y1, x2, y2, x3, y3, color)for drawing triangle outlines
and filled triangles from three points. Filled-triangle vertex order is
auto-corrected so arrows, spaceship nosecones, and pointer shapes draw
regardless of how you specified the points.
See #211 - New
gfx.COLOR_TRUE_WHITEconstant: an off-palette pure(255, 255, 255)
white. Use it as the identity tint forgfx.spr_exandgfx.sspr_exwhen you
want sprite pixels to pass through unchanged. The Pico-8gfx.COLOR_WHITEis
slightly warm (255, 241, 232) and tints sprites a touch peachy if used as
the identity, which is fine if you want a warm look but undesirable if you're
after pure pass-through. Available in every API that takes a palette index
(gfx.text,gfx.clear,gfx.rect, etc.) and stays pure white even with a
custompalette.pngloaded. - New examples:
- scene_switching: how to define multiple scenes like gameplay, main menu,
etc. and switch between them
- scene_switching: how to define multiple scenes like gameplay, main menu,
- The credit for the open source code that Usagi depends on is now included in
the engine's archive, detailing the various licenses. These are also viewable
at https://usagiengine.com/third-parties. USAGI_VERBOSE=1now emits a one-shot startup snapshot at boot (build
profile, platform, GC params, resolution, sprite size, pause-menu / palette /
font source, script path, Lua heap after_init) plus a per-second frame
summary line (avg / p50 / p99 / max frame time in ms, count of frames over the
16.7 ms budget, current Lua heap KB). The frame summary catches silent perf
regressions of the "still runs but slower" shape; the snapshot pins the env
for bug reports. Zero overhead when the env var is not set.- New
examples/diagnosticsto exercise both: short-lived table allocs in
_updatewith controls to scale the rate, plus a one-shot burst button to
provoke a GC cycle. Run asUSAGI_VERBOSE=1 just example diagnosticsand
watch the terminal. - Raylib's own boot chatter and per-frame TEXTURE log are now gated on a
separateUSAGI_RAYLIB_VERBOSE=1, so the diagnostics stream stays readable.
Previously both sharedUSAGI_VERBOSE=1and raylib's per-frame log buried the
frame summary. Set both env vars when you need everything.
Fixes:
- GIF recordings now use 255 colors instead of the default Pico-8 color palette,
fixing an issue where exported GIF colors were wrong.
See #222 - macOS no longer prints the GLFW "regular windows do not have icons on macOS"
warning at startup. Cocoa never honored the per-window icon anyway, so the
call was a known no-op; the.appbundle'sAppIcon.icnsis the path that
matters there, and it's still generated atusagi export --target macostime. - Passing a non-UTF-8 byte sequence (e.g.
string.char(200)) to engine APIs
that take a string (gfx.text,gfx.text_ex,usagi.measure_text,
usagi.menu_item,sfx.play,music.play,gfx.shader_set, etc.) no longer
crashes on Windows. Bytes outside ASCII render as the U+FFFD replacement
character instead of erroring at the FFI boundary. - Error overlay text renders cleanly on Windows setups where the bundled font
was previously upscaled at a fractional ratio and came out blurred / curly.
The overlay now draws at an integer multiple of the bundled monogram's native
size. See #212 usagi.savenow rejects unsupported table shapes with a clear message instead
of either a cryptic serde error or silent data loss. Tables with sparse
integer keys ({[6]=1, [7]=2}), gaps in a 1..n array ({[1]="x", [3]="z"}),
or mixed string/integer keys now error up front and point at the workaround.
JSON only supports maps with string keys or dense1..narrays.
See #220- Fixed slow shutdown after long sessions: switched Lua from generational to
incremental garbage collection, which keeps the heap bounded during play so
closing doesn't stall sweeping accumulated dead objects on exit.
See #232 - Pause menu now always uses the engine's color palette (Pico-8) so that custom
color palettes don't inadvertently lead to illegible pause menu colors.
Assets 11
v0.8.0
b3171ad Usagi v0.8.0 comes with a ton of new features leading up to the v1.0.0 release.
This will be the last release before v1.0.0. A lot of what's new comes by way
of feedback from the community and what I've been needing for my own
games. The engine's feeling good and stable! It's a great time to jump in.
v0.8.0 includes support for custom color palettes, custom fonts, advanced
shape and sound APIs, gamepad action button remapping, Lua 5.5 support
and more!
Check out the full details below.
Install
If you have Usagi installed, use usagi update and then usagi refresh
if you want to update the docs to the new version.
There's a new way to get Usagi via install scripts if you don't have
it installed already:
Linux, macOS:
curl -fsSL https://usagiengine.com/install.sh | shWindows (PowerShell):
irm https://usagiengine.com/install.ps1 | iex
Or just download for your operating system below.
Breaking:
- Color slot indices are now 1-based instead of 0-based, matching
gfx.spr
and Lua's array convention. Thegfx.COLOR_*constants shift up by one.
gfx.COLOR_BLACKis now1(was0),gfx.COLOR_PEACHis16(was15).
Code that uses the named constants is unaffected; code that passes literal
integers (gfx.clear(0),gfx.rect_fill(..., 7)) needs to bump each literal
by 1 or switch to the named constants. Slot0and any index above the active
palette's length now render as the magenta out-of-range sentinel. gfx.spr_exandgfx.sspr_exgained three required trailing params:
rotation(radians),tint(palette color), andalpha(0..1). Use
0, gfx.COLOR_WHITE, 1.0for the identity values to preserve the old
behavior. The simplegfx.spr/gfx.ssprsignatures are unchanged. See the
README's "Scaling sprites" subsection for wrapper recipes if you find the
verbose call sites painful.
Features:
- Custom color palettes via
palette.png. Drop a PNG at your project root and
Usagi swaps the default Pico-8 palette for yours. Pixels read in row-major
order (left-to-right, top-to-bottom) so any rectangular shape works. 16x1
strips, 16x2 grids, 4x4 grids, etc. Color count =width ×ばつ height.
lospec.com's "1px cells" exports are the canonical source. Hot-reloads like
sprites.png, ships inusagi exportbundles. Thegfx.COLOR_*constants
stay as slot indices, so they keep resolving through the same slots, but the
RGB at each slot is whatever you painted. Slots beyond your palette's range
render as magenta. The ColorPalette tool reflects the active palette. New
examples/palette_swapships a sweetie16 palette; delete itspalette.pngto
see the same Lua in Pico-8 colors. - New
sfx.play_ex(name, volume, pitch, pan),
music.play_ex(name, volume, pitch, pan, loop), and
music.mutate(volume, pitch, pan)for programmatic audio control.play_ex
is fire-and-forget per-call params (use it for random-pitch footsteps, panned
UI cues, attenuated dialogue beeps).music.mutatemodulates the
currently-playing track in place with replace semantics. This is useful for
ducking music under dialog, pitch-warping during hitstun, and fade-outs. Pan
is-1..1(left to right), volume0..1, pitch a raw multiplier (1.0=
identity). Theexamples/sounddemo gets a random-pitch jump on BTN3;
examples/musicducks the track while LEFT is held. - New
gfx.text_ex(text, x, y, scale, rotation, color)for scaled and rotated
text. Scale is a font-size multiplier (use integers for crisp pixel-art text;
fractional values blur). Rotation is in radians (usemath.rad(deg)for
literal degrees) and pivots around the text's center. Newexamples/text
shows a big scaled title, a sin-wave wiggling subtitle, and a static tilted
label. - New
gfx.rect_ex(x, y, w, h, thickness, color),
gfx.circ_ex(x, y, r, thickness, color), and
gfx.line_ex(x1, y1, x2, y2, thickness, color)for thick-stroke shape
outlines.circ_exstrokes are centered on the nominal radius so concentric
rings at adjacent radii sit flush instead of leaving rounding gaps. The
examples/shapesdemo now includes a small concentric-rings showcase. gfx.spr_ex/gfx.sspr_exnow support rotation, tint, and alpha. Rotation
is in radians (usemath.rad(deg)for literal-degree values) and pivots
around the sprite's center. Tint is a palette color multiplied over the sprite
(gfx.COLOR_WHITEis the identity; other colors recolor for hit flashes
etc.). Alpha is0..1for fade-in/out. Theexamples/sprdemo now exercises
all three (spinning bunny, tint-flashing ship via BTN1, pulsing-alpha bullet).- New
input.mouse_scroll()returns the per-frame vertical scroll delta
(positive up, negative down,0when no scroll). Works the same on a mouse
wheel or a trackpad two-finger swipe. The mouse example now uses it to cycle
the spark color. - Upgraded the embedded Lua runtime from 5.4 to 5.5. No game-code changes are
expected for typical Usagi scripts; the bundled.luarc.json(shipped via
usagi init/usagi refresh) now pinsruntime.versiontoLua 5.5so the
LSP matches. - TilePicker: LMB on a tile copies its
sprindex (existing behavior). RMB
click-and-drag now selects a tile-aligned rectangle on the sheet and copies
sx,sy,sw,shready forsspr. The current selection stays visible: a
highlight box on the sheet plus a readout in the header showing both thespr
index (for single tiles) and thessprsource rect. A live preview rect
tracks the drag. sprites.pngis now explicitly loaded with POINT (nearest-neighbor) texture
filtering, matching the bundled font, so the pixel-art intent is pinned in the
engine rather than relying on a default.- TilePicker: hold middle mouse and drag, or hold space and drag with the left
mouse, to pan the sheet. Use the scroll wheel to zoom (anchored on the cursor
so the pixel under the mouse stays put). The header also shows the sheet pixel
coords under the cursor. - New
usagi.dump(v)helper: pretty-prints any Lua value to a string, recursing
into tables with sorted keys and cycle detection. Pair withprintfor
terminal debugging, or feed intogfx.textto draw on screen. - New
gfx.px(x, y)reads a pixel from the most recently rendered frame and
returns(r, g, b, palette_index)as multiple values. The palette index is
the 1-based slot for an exact RGB match, ornilfor off-palette colors. All
four returns arenilfor off-screen coordinates or on the very first frame
before any drawing has happened. Reads reflect the previous frame's finished
image, so they don't see in-progress draws inside the current_draw. Useful
for collision-by-color, fog-of-war reveals, palette-swap effects, and water
reflections. - New
gfx.spr_px(index, x, y)reads a pixel fromsprites.png.indexis a
1-based sprite slot (same shape asgfx.spr);(x, y)is the offset inside
that cell. Returns the same(r, g, b, palette_index)shape asgfx.px. All
four returns arenilfor an out-of-range index, out-of-cell coordinates, a
project with nosprites.png, or a fully transparent source pixel (so the
ergonomicif r then ...check covers both "no sheet" and "alpha hole"
cases). Useful for pixel-perfect sprite collision and for data-baked levels
where you paint the layout into the sheet and scan it at startup. - New
examples/pxcart demonstrates both reads side-by-side: a small maze
where movement consultsgfx.pxfor collision-by-color, plus agfx.spr_px
scan that re-renders sprite 1 pixel-by-pixel next to itsgfx.sproriginal. - Bundled font upgraded from monogram (95 ASCII glyphs) to monogram-extended
(504 glyphs covering full Basic Latin, Latin-1 Supplement, Latin Extended-A,
partial Greek and Cyrillic). Text likecafé naïve jalapeño,
Здравствуй, мир!, andΚαλημέρα κόσμεnow render. Same look, same line
height, just more codepoints. Updatedexamples/textshows the new chars. - Custom font support: drop
font.pngat your project root and Usagi uses it
forgfx.text/gfx.text_ex/usagi.measure_text. Engine UI (FPS overlay,
pause menu, error text) keeps the bundled font so layout stays predictable
regardless of what you ship. The font's natural line height drives
font.base_size()at runtime, so larger or smaller fonts render at their
design size with no scaling. - New
usagi font bake <font.ttf> <size>subcommand bakes a TTF/OTF into the
custom-font format (a single PNG with glyph metadata embedded as a zTXt
chunk). Defaults to writingfont.pngin the current directory, so the output
is immediately a project drop-in. Includes the CJK Unified Ideographs block by
default for fonts that cover it (kanji/hanzi/hanja); pass--no-cjkto skip.
Pass the font's natural design size for crispest output (e.g.,15for
monogram-style ×ばつ7 fonts,18for Silver,8for Misaki Gothic). New
examples/custom_fontships a Silver-baked demo with multi-script text. - Per-game gamepad remapping for BTN1/BTN2/BTN3 alongside the existing keyboard
remapping. New "Configure Gamepad" entry under the pause menu's Input
sub-menu, mirroring the Pico-8-style sequential capture flow used by
"Configure Keys": face buttons and shoulder/trigger positions are bindable;
dpad, Select/Start/Home, and stick clicks are reserved. Bksp or Select undoes
the previous capture; Del or Start resets every override. Overrides persist
per game aspad_map.jsonnext tokeymap.json. Pause titles renamed to
KEYBOARD CONFIGandGAMEPAD CONFIG. - Pause menu reorganized: a new Settings sub-menu now holds Music, SFX,
Fullscreen, and Input, so the Top stays focused on Continue plus the
destructive acti...
Assets 11
v0.7.2
8e197a0 Bunch of small fixes before I release Bomberfrog: Alpha.
Get it with usagi update or download below.
Fixes:
input.mapping_fornow properly returns the key string instead of"?"for
custom mappings.- VSync enabled for the engine to fix screen tearing. See
#132
Assets 11
v0.7.1
57a8209 Web is the Dark Souls of build targets...
Get the latest with usagi update or download below.
Features:
- Usagi version is logged on game start.
- Raylib log level is set to warning to reduce noise. Set env var
USAGI_VERBOSE=1to get full Raylib logs.
Fixes:
- Web games don't crash when loading due to fullscreen error. See
#154 - Web games now load with default shell. They no longer display a black screen.
Fixes CSS error introduced in v0.7.0.
Assets 11
v0.7.0
4b29343 Usagi v0.7.0 is primarily a bug fix release but includes two new
little features.
Update with usagi update and then run usagi refresh in your project.
Or download below if it's your first time using Usagi.
Features:
MOUSE_MIDDLE(a.k.a. scroll wheel click) support for mouse input checks.effect.stop()to end all currently running effects.
Fixes:
input.pressedandinput.releasednow edge-detect the analog stick the same
way they do the d-pad, so menus (including the engine pause menu) can be
navigated with the left stick.- Closing and opening the menu swallows input so that it doesn't accidentally
trigger presses. See #130 - Live reload with
usagi dev main.luaorusagi dev game.luanow works again.
Nested paths orusagi devworked as expected in v0.6.1 but passing a
filename within the current directory would break live reload. See
#136 - Enter no longer closes the Pause menu when it's open but instead is
used to confirm the selection. It was awkward as a toggle. - Toggle fullscreen now works on web.
- "Quit" Pause menu option is now hidden on web since it didn't do anything.
- Up and down page navigation keyboard keys no longer scroll the page for web
builds. Before this up and down, etc. were scroll page, not registering as
game input. See #112 - Effects reset when the game resets. Before they'd keep running, shaking the
screen or hitstopping when they shouldn't.
Assets 11
v0.6.1
4ad9e6c Assets 11
v0.6.0
4dd2ecd NOTE: Download v0.6.1, it includes fixes for usagi dev crashing on
Windows when there are Lua syntax errors and invalid args passed:
https://github.com/brettchalupa/usagi/releases/tag/v0.6.1 or
https://github.com/brettchalupa/usagi/releases/latest
I intended to wait a bit longer before the v0.6.0, but I think the new effects,
custom resolution, and custom sprite size are exciting enough to deserve their
own release. This release also lays the foundations for usagi update to work
when the next release rolls around.
You can run usagi refresh in your projects to regenerate the ancillary files
to improve the developer experience, like USAGI.md, the meta file, etc.
Also, rejoice, errors no longer flood stdout and instead only show once
until the error changes or goes away.
Warning: white flash near the end of the video.
Usagi.Effects.Demo.webm
Features:
-
Experimental
usagi updatecommand to update the binary in place when new
versions are released. Won't be useful and fully testable until the next
release comes out. -
usagi refreshcommand to update the ancillary engine files when a new
version is released. Currently updatesmeta/usagi.lua,.luarc.json, and
USAGI.md. Does not updatemain.lua. Use this afterusagi updateto
get the docs and LSP integration for theusagi -Vyou're using. -
New
effect.*Lua module for engine-level juice. Four primitives, all decay
automatically once per frame:effect.hitstop(time)freezes_updatefortimeseconds.effect.screen_shake(time, intensity)shakes the blit, magnitude in game
pixels, decays linearly.effect.flash(time, color)full-screen palette-color overlay that fades
from opaque to transparent.effect.slow_mo(time, scale)scales thedtpassed to_update;
scale=0.5is half-speed,scale=0freezes (usehitstopfor that).
Stacking rule across all four: longer duration wins, latest magnitude wins;
spam-calling is safe. Seeexamples/effect.luafor a runnable demo. The
notetrisexample now useseffect.screen_shakein place of its bespoke
shake.
-
New
usagi.SPRITE_SIZEconstant (default16) for tile-grid math without
hardcoding the cell size. Same value the engine uses internally forgfx.spr
indexing, the tilepicker tool, and the window-icon slicer. Override the
default by setting_config().sprite_size; the new value flows through every
consumer (Lua draws, icon slice on session andusagi export --target macos,
tilepicker grid inusagi tools). -
_config()can override the game's render resolution viagame_widthand
game_height(defaults 320 and 180). The internal RT is sized to those dims;
usagi.GAME_W/GAME_Hreflect the active values. Tested band is roughly
320x180 to 640x360; pause-menu and tools UI are pixel-fixed and may overflow
at very small sizes or look sparse at very large ones. The web export
templates the canvas backing-store and aspect ratio from the configured
resolution, so non-16:9 / non-default games ship correctly with the default
shell (no--web-shellneeded) and embed cleanly in itch at any iframe size.
Sprite size and bundled font are still fixed at 16 and 5x7.function _config() return { game_width = 480, game_height = 270 } end
Fixes:
- A persistent error in
_updateor_drawno longer spams stderr 60x/sec.
record_errnow logs only when the message changes; the on-screen overlay
still updates every frame, so users see live changes when they edit and save.
Assets 11
v0.5.0
0b7505a Usagi v0.5.0 includes a bunch of handy new input APIs and a fully-featured
Pause menu with volume control and input mapping! See the full
details below.
Breaking:
input.down(action)is renamed toinput.held(action)and
input.mouse_down(button)toinput.mouse_held(button). The old names
collided with directional input names (input.down(input.DOWN)was ambiguous)
and "held" reads more naturally as the level-state pair to the edge-state
pressed/released. Update calls; behavior is unchanged.settings.jsonreplaces the singlevolumekey withmusic_volumeand
sfx_volume. Existing settings are auto-migrated on load: the oldvolume
value is copied into both new fields the first time the engine reads them. No
action required.
Features:
- Pause Menu is now navigable. Up/Down moves between items, Left/Right adjusts
values, BTN1 (Z/gamepad-A) confirms, BTN2 (X/gamepad-B)
goes back. Items: Continue, Music volume, SFX volume, Fullscreen, Input, Clear
Save Data (with a confirm dialog), Reset Game, Quit. - Music and SFX have separate persisted volume levels, each rendered as a 5-bar
meter (steps of 20%). Default is 80% for both. - Shift+M now mutes both channels at once and a second
press restores both to their defaults. - Pause Menu's Input view shows a live tester (D-pad + button rects light up
while pressed) and a "Configure Keys >" entry that opens a Pico-8-style
keyconfig flow: highlights one action at a time, captures one key, advances.
Esc cancels, Delete resets all overrides. Keyboard-only
for now; gamepad bindings stay fixed. The new mappings persist per-game in
keymap.jsonnext tosettings.json(web: localStorage
usagi.keymap.<game_id>). Override semantics are "replace": once you map LEFT
to W, the default arrow Left no longer fires LEFT. - Switch face buttons follow Nintendo convention: BTN1 fires from A (east) and
BTN2 from B (south), so "A confirms, B cancels" feels native on Switch. Xbox
and PlayStation are unchanged (BTN1=south, BTN2=east). Triggers (LB/RB) and
BTN3 stay put across all families. - New Lua API for source-aware control glyphs:
input.mapping_for(action)
returns the label of the active source's primary binding (e.g."Z"while the
player is on keyboard;"A"on Xbox,"Cross"on PlayStation,"B"on
Switch when the active source is gamepad). Gamepad family is auto-detected via
GetGamepadNameand falls back to Xbox for unknown / generic / Steam Deck
pads. The engine tracks the most recent source automatically, switching only
when a bound input fires so stray keys don't flip it.input.last_source()
returns"keyboard"or"gamepad"; matching constants are
input.SOURCE_KEYBOARDandinput.SOURCE_GAMEPAD. Examples that previously
hardcodedBTN1/BTN2/BTN3in their on-screen prompts (sound, music, save,
shader, rng, snake, dialog, operators, mouse) now useinput.mapping_forso
the prompts adapt to the active device. - New input functions:
input.released(action)and
input.mouse_released(button)fire the frame the input transitions from held
to up. Mirrorspressedfor the release edge; useful for charge-and-release
mechanics (jump-on-release, slingshot pull-back). - New
utilglobal with drop-in math/geometry helpers:util.clamp,
util.sign,util.round,util.approach,util.lerp,util.wrap,
util.flash,util.vec_normalize,util.vec_dist,util.vec_dist_sq,
util.vec_from_angle,util.point_in_rect,util.point_in_circ,
util.rect_overlap,util.circ_overlap,util.circ_rect_overlap. Pure Lua,
available withoutrequire. Source is atruntime/util.luafor forkability.
Open it to read the implementations or override individual functions in your
own_init. Functions that take shaped tables check the shape and raise an
error pointing at your call site (e.g.
util.rect_overlap: arg 1 table missing or non-numeric field 'h') instead
of failing deep inside the helper.util.min/util.maxaren't included
since Lua'smath.min/math.maxalready do the job. - Direct keyboard reads via
input.key_pressed(key),input.key_held(key), and
input.key_released(key), paired withinput.KEY_*constants for letters,
digits, F1–F12, arrows, modifiers, common punctuation, and a few specials
(Space, Enter, Escape, Tab, Backspace, Delete). Documented as an escape hatch
— these bypass the keymap override and gamepad bindings, so they're intended
for dev hotkeys (e.g. F1 to toggle a debug overlay) and
keyboard-and-mouse-only games. Anything a player should be able to remap or
reach with a controller still belongs on the abstractinput.held/
input.pressed/input.releasedactions. Raw gamepad reads remain
intentionally unexposed. - CLI output is now color-coded: success and reload messages render in green,
warnings (graceful fallbacks like a missing keymap or skipped export target)
in yellow, and errors in red. The[usagi]prefix is dimmed so the message
itself reads as the foreground content. Reload messages no longer look like
errors at a glance. Color is auto-disabled when stdout isn't a terminal
(piping to a file, CI logs) or whenNO_COLORis set, per
https://no-color.org.
Fixes:
- Alt+Enter no longer opens the Pause Menu while toggling
fullscreen. Pause Menu only opens on Enter when Alt isn't held. usagicommands now correctly log the output on Windows and the exported game
window does not show them, see #79.