Repository navigation
Releases
Riftlight (latest main)
Riftlight as one self-contained HTML file (6.8M), built from main at 7355466 after CI passed. Download it and open it in a browser with WebGPU (Chrome or Edge); it runs offline from file://. Add ?game=world, ?game=playground, ... to the URL for the other games. Replaced on every green main.
Pixel Engine 0.48.0
Pixel Engine 0.48.0 as the engine kit: pixel-engine.zip below holds the engine as one ES module, its guides, a starter game and check.mjs. Unzip it, then read README.md and GUIDE.md.
The newest release is always https://github.com/michaelcrosato/riftlight/releases/latest/download/pixel-engine.zip; this one stays at https://github.com/michaelcrosato/riftlight/releases/download/engine-v0.48.0/pixel-engine.zip.
What changed in 0.48.0
HubSession.offline(info): a round with no hub behind it, for replaying a recorded session (its
events are recorded input): it sends and reports nothing, and its clock never starts.RemoteTrack.senderTime(now): the moment of the sender's clock being drawn, to apply what it
did up to then (its inputs, its events) in step with the motion.
Pixel Engine 0.47.0
Pixel Engine 0.47.0 as the engine kit: pixel-engine.zip below holds the engine as one ES module, its guides, a starter game and check.mjs. Unzip it, then read README.md and GUIDE.md.
The newest release is always https://github.com/michaelcrosato/riftlight/releases/latest/download/pixel-engine.zip; this one stays at https://github.com/michaelcrosato/riftlight/releases/download/engine-v0.47.0/pixel-engine.zip.
What changed in 0.47.0
- AI Hub sessions (docs/engine/hub.md):
HubSession.join({ mode, seats })takes part in a round of
the AI Hub (AI Hub Session Protocol v1) inparallel,ghostorshared-worldmode, and is null
outside one. The hub's events (start, other copies'messages,leave,time-up,end) arrive as
input commands (hubEvents(ctx.input.commands)), so a session records and replays.progress,
resultandfinish(once, and only an outcome the hub can take),send(bundled per destination
under the hub's rate and size limits; what the rate holds back waits), and atendthe engine
stands still (speed 0) and goes quiet.RemoteTrackdraws another copy's state smoothly;LocalHub
is the hub in memory for tests, held to the real client's limits.HUB_COLORS,HUB_LIMITS,
headMeta,validResult,validFinish. - Languages (docs/engine/lang.md, AI Hub Languages v1):
LangandlangFor(lines)give lines in
the player's language witht(id, values): blanks, plural forms, control tags, numbers formatted for
the language, right-to-left isolates, and the original line whenever a translation is missing or
broken.pickLanguage,languageName,chooseLanguage, the test languagesen-XA,zh-XC,
ar-XB(fakeLine),pieces,lineWidth,blockJson,pageBlock,HUB_LANGUAGES. - Text in every writing system: the pixel font composes accented capitals (
glyphFor: É, Ñ, Ç, Ş,
İ, Ẹ́, plus ¿ ¡ « » „ – — … € Æ Œ Ø Ɓ Ɗ Ƙ) and upper-cases in the drawing language
(setTextLocale). A line in a language it can't draw (Cyrillic, Chinese, Arabic, Hindi,
Vietnamese...) is drawn byctx.hudin the device's own font at the screen's resolution, in the same
box (pixelCovers,drawDeviceText,surfaceScale).hud.measureandtextWidthPxmeasure the
font that draws;wrapTextwraps by measured width atIntl.Segmenterword breaks.textWidthcounts
letters with their marks, not UTF-16 units. - Gamepad: View + Menu held together (buttons 8 and 9,
HOST_CHORD) press neither until both are
let go: the AI Hub opens its bar on them.
Pixel Engine 0.46.0
Pixel Engine 0.46.0 as the engine kit: pixel-engine.zip below holds the engine as one ES module, its guides, a starter game and check.mjs. Unzip it, then read README.md and GUIDE.md.
The newest release is always https://github.com/michaelcrosato/riftlight/releases/latest/download/pixel-engine.zip; this one stays at https://github.com/michaelcrosato/riftlight/releases/download/engine-v0.46.0/pixel-engine.zip.
What changed in 0.46.0
- No more handoff page: the engine's site is gone, so
manifest.jsonhas nohandoffand the
kit'sREADME.mdno longer names a page for agents. Newer kits are where they were:
latest(the newest release's zip),releasesandsource.
Pixel Engine 0.45.0
Pixel Engine 0.45.0 as the engine kit: pixel-engine.zip below holds the engine as one ES module, its guides, a starter game and check.mjs. Unzip it, then read README.md and GUIDE.md.
The newest release is always https://github.com/michaelcrosato/riftlight/releases/latest/download/pixel-engine.zip; this one stays at https://github.com/michaelcrosato/riftlight/releases/download/engine-v0.45.0/pixel-engine.zip.
What changed in 0.45.0
- The kit runs in Node:
Engine.headless(game, { assets })frompixel-engine.jsalone, with
nonode_modules. In Node, Rapier's wasm comes from the data URL the kit inlines, and a reader
(assets,setAssetReader) no longer sees the files the kit embeds (__PIXEL_ASSETS__: the
built-in models load as they do in a page). node check.mjs --headless game.js: plays a game module in Node, no browser. It makes the game
with the module'screateGame()export, plays the--keysframes, replays the recording in a
fresh game and writesreport.json(state(), errors, the fingerprint). Exit 1 on an error or a
replay that ends elsewhere, 2 for a page or a module withoutcreateGame().- The starter
game.jsexportscreateGame()and starts the engine only where there is a
document, so it imports in Node. GUIDE.md section 8, Play it in Node, shows a test of your own.
Pixel Engine 0.44.0
Pixel Engine 0.44.0 as the engine kit: pixel-engine.zip below holds the engine as one ES module, its guides, a starter game and check.mjs. Unzip it, then read README.md and GUIDE.md.
The newest release is always https://github.com/michaelcrosato/riftlight/releases/latest/download/pixel-engine.zip; this one stays at https://github.com/michaelcrosato/riftlight/releases/download/engine-v0.44.0/pixel-engine.zip.
What changed in 0.44.0
- Removed from the texture library: its equipment icons:
sword-icon,axe-icon,
mace-icon,dagger-icon,bow-icon,staff-icon,wand-icon,shield-icon,
round-shield-icon,quiver-icon,helmet-icon,armor-icon,gloves-icon,boots-icon,
belt-icon,ringandamulet. They were a second way to draw an item next to Riftlight's own
icons, which fill any item footprint (a one-cell item's box is 7 px wide), and nothing used them. A game that wants one makes its own
TextureDef(docs/GUIDE-ASSETS.md) and adds it withTEXTURE_LIBRARY.add(def). The library
keeps the items Riftlight has no class for (potions, key, scroll, map, book, bomb, torch...),
gem-icon,gold-icon, the skill and UI icons and the creatures.
Pixel Engine 0.43.0
Pixel Engine 0.43.0 as the engine kit: pixel-engine.zip below holds the engine as one ES module, its guides, a starter game and check.mjs. Unzip it, then read README.md and GUIDE.md.
The newest release is always https://github.com/michaelcrosato/riftlight/releases/latest/download/pixel-engine.zip; this one stays at https://github.com/michaelcrosato/riftlight/releases/download/engine-v0.43.0/pixel-engine.zip.
What changed in 0.43.0
Game.args: the plain JSON a game was made with, when its name alone can't rebuild it (a
lab's depth and seed, the door a room was entered by). Recordings keep it (Recording.args),
so a tool can make the same game again and replay one (npm run replayin this repository).
Pixel Engine 0.42.0
Pixel Engine 0.42.0 as the engine kit: pixel-engine.zip below holds the engine as one ES module, its guides, a starter game and check.mjs. Unzip it, then read README.md and GUIDE.md.
The newest release is always https://github.com/michaelcrosato/riftlight/releases/latest/download/pixel-engine.zip; this one stays at https://github.com/michaelcrosato/riftlight/releases/download/engine-v0.42.0/pixel-engine.zip.
What changed in 0.42.0
Engine.headless(game, options): games without a page (docs/engine/headless.md). The same
boot, game code and frames asEngine.start, in Node: no GPU, DOM or listeners, manual time from
the start (step(),input.setKey/send,replay()), errors inengine.errors. Options add
viewport(default 960×540 at DPR 1) andassets.engine.rendereris aView: what gameplay reads from a view (art resolution, framing,
viewport, look, mode, filters,screen,capture()), the page'sPixelRendereror a
HeadlessView. Direct GPU work goes throughengine.gpu(thePixelRenderer, null
headless):engine.renderer.rendererbecomesengine.gpu.renderer.BackendNamegains
'headless'.- The GPU helpers take the view:
swarm.update(engine.renderer, dt)(was
engine.renderer.renderer),mirror.attach(engine.renderer, scene)and
view.attach(engine.renderer, scene)as before; headless they do nothing. - New exports:
HeadlessOptions,View,HeadlessView(setViewport),HeadlessViewOptions,
HEADLESS_VIEWPORT,frameView,Viewport,setAssetReader,AssetReader. - Assets without
fetch:setAssetReader(read)reads models and packs through
(path) => Promise<ArrayBuffer>for the whole process (AssetReader);nodeAssets()in
src/engine/node.tsreadspublic/in Node. A model load that fails is tried again on the
next call instead of failing from the cache. Recording.view: the viewport a recording was made on. A headless replay frames for it; a
page warns when its own differs (pointer aim and the HUD follow it).frameViewandViewport
are the framing both views share.- The HUD's
width/heightfollow the view from the first frame, before anything is drawn.
Pixel Engine 0.41.0
Pixel Engine 0.41.0 as the engine kit: pixel-engine.zip below holds the engine as one ES module, its guides, a starter game and check.mjs. Unzip it, then read README.md and GUIDE.md.
The newest release is always https://github.com/michaelcrosato/riftlight/releases/latest/download/pixel-engine.zip; this one stays at https://github.com/michaelcrosato/riftlight/releases/download/engine-v0.41.0/pixel-engine.zip.
What changed in 0.41.0
- One readiness signal:
window.__PIXEL_READY__. A promise that exists as soon as the engine
loads, resolves with the engine whenEngine.starthas finished and rejects with the reason a
start failed. Tools await it instead of polling for__PIXEL_ENGINE__. Game.ready(ctx). An optional hook the engine calls when it starts running a game (just
before__PIXEL_READY__resolves) and after eachloadGame: put a game's page handles for tools
there, so they never exist before the engine can step. An exception in it is reported like any
hook's (engine.errors, on screen) and the game runs on. A game whose class already had a
readymember that isn't this hook must rename it.engine.step()before the first start throws (engine not ready: await window.__PIXEL_READY__) instead of running 0 frames and leaving the game frozen in manual time.
During a laterloadGameit still runs 0 frames.
Pixel Engine 0.40.0
Pixel Engine 0.40.0 as the engine kit: pixel-engine.zip below holds the engine as one ES module, its guides, a starter game and check.mjs. Unzip it, then read README.md and GUIDE.md.
The newest release is always https://github.com/michaelcrosato/riftlight/releases/latest/download/pixel-engine.zip; this one stays at https://github.com/michaelcrosato/riftlight/releases/download/engine-v0.40.0/pixel-engine.zip.
What changed in 0.40.0
- No engine hotkeys in a shipped game. P, R, `, [ ], M are developer tools: on with the debug
panel (the dev server,?debug=1), off otherwise.debugKeys: true/falseturns them on /
off always; an object (DebugKeyChanges:{ resolution: 'F2' }) still moves or drops single
keys, and no longer turns them on.resolveDebugKeys()with nothing now gives none (true: the
defaults), andrebindDebugKeys(keys, changes)moves only the keys that are on, so a game that
moves R off its own key at runtime never turns the hotkeys back on. The debug panel lists only
the hotkeys that are on, under their keys, and the touch bar's debug button is ⓘ (⚙ is the
settings). - Player settings (
engine.settings,PlayerSettings): look, pixel art or smooth 3D, pixel
size, quality, frame rate and debug info, as plain data saved per game (EngineOptions.settings.key,
default the first game's name) and applied over the game's own choices. A field left out is the
game's;set,reset,replace,values,onChange. A review flag in the URL wins over a
saved value at start (which stays saved), and a chosen look wins over each new level's own. A
replay saves nothing and puts the player's settings back when it ends. - The settings panel, with the sound volumes, opens from the ⚙ button (
settings.button: a
corner, default top-right; on a mouse it shows while the pointer moves;falsefor none) or
engine.settings.open(). It pauses the game while open, keys pressed in it never reach the
game, and it stays shut while a replay plays. Its Look is off while pixel art is: smooth 3D
draws no look. Alsoengine.useQuality(option)(auto: the device's level, lowered once by a
measurement),engine.showDebug(on),engine.debugShownandaudio.resetVolumes().